From 2d64b5bbed43c33ee0fef70822e324646963939d Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 23 Jan 2018 15:58:23 -0500
Subject: [PATCH 14/14] FIXME: WIP on named types in libcpp

---
 gcc/coverage.c              |   6 +-
 gcc/diagnostic-show-locus.c | 269 +++++++++++++++++++++++---------------------
 gcc/diagnostic.h            |   6 +-
 gcc/final.c                 |   4 +-
 gcc/gimple.h                |   4 +-
 gcc/input.h                 |   3 +-
 libcpp/directives-only.c    |   2 +-
 libcpp/directives.c         |  23 ++--
 libcpp/include/line-map.h   | 222 ++++++++++++++++++++++++++++--------
 libcpp/internal.h           |  10 +-
 libcpp/line-map.c           |  56 +++++----
 libcpp/macro.c              |   4 +-
 12 files changed, 378 insertions(+), 231 deletions(-)

diff --git a/gcc/coverage.c b/gcc/coverage.c
index 32ef298..7ed63cf 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -555,7 +555,7 @@ coverage_compute_lineno_checksum (void)
 {
   expanded_location xloc
     = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
-  unsigned chksum = xloc.line;
+  unsigned chksum = xloc.line.get_value ();
 
   if (xloc.file)
     chksum = coverage_checksum_string (chksum, xloc.file);
@@ -665,8 +665,8 @@ coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
 		     (DECL_ASSEMBLER_NAME (current_function_decl)));
   gcov_write_unsigned (DECL_ARTIFICIAL (current_function_decl));
   gcov_write_filename (xloc.file);
-  gcov_write_unsigned (xloc.line);
-  gcov_write_unsigned (xloc.column);
+  gcov_write_unsigned (xloc.line.get_value ());
+  gcov_write_unsigned (xloc.column.get_value ());
 
   expanded_location endloc = expand_location (cfun->function_end_locus);
 
diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c
index 6b2111c..4284642 100644
--- a/gcc/diagnostic-show-locus.c
+++ b/gcc/diagnostic-show-locus.c
@@ -115,8 +115,8 @@ class layout_point
   : m_line (exploc.line),
     m_column (exploc.column) {}
 
-  int m_line;
-  int m_column;
+  line_num m_line;
+  column_num m_column;
 };
 
 /* A class for use by "class layout" below: a filtered location_range.  */
@@ -129,8 +129,8 @@ class layout_range
 		bool show_caret_p,
 		const expanded_location *caret_exploc);
 
-  bool contains_point (int row, int column) const;
-  bool intersects_line_p (int row) const;
+  bool contains_point (line_num row, column_num column) const;
+  bool intersects_line_p (line_num row) const;
 
   layout_point m_start;
   layout_point m_finish;
@@ -144,8 +144,8 @@ class layout_range
 
 struct line_bounds
 {
-  int m_first_non_ws;
-  int m_last_non_ws;
+  column_num m_first_non_ws;
+  column_num m_last_non_ws;
 };
 
 /* A range of contiguous source lines within a layout (e.g. "lines 5-10"
@@ -155,15 +155,15 @@ struct line_bounds
 
 struct line_span
 {
-  line_span (linenum_type first_line, linenum_type last_line)
+  line_span (line_num first_line, line_num last_line)
     : m_first_line (first_line), m_last_line (last_line)
   {
     gcc_assert (first_line <= last_line);
   }
-  linenum_type get_first_line () const { return m_first_line; }
-  linenum_type get_last_line () const { return m_last_line; }
+  line_num get_first_line () const { return m_first_line; }
+  line_num get_last_line () const { return m_last_line; }
 
-  bool contains_line_p (linenum_type line) const
+  bool contains_line_p (line_num line) const
   {
     return line >= m_first_line && line <= m_last_line;
   }
@@ -172,14 +172,14 @@ struct line_span
   {
     const line_span *ls1 = (const line_span *)p1;
     const line_span *ls2 = (const line_span *)p2;
-    int first_line_diff = (int)ls1->m_first_line - (int)ls2->m_first_line;
-    if (first_line_diff)
-      return first_line_diff;
-    return (int)ls1->m_last_line - (int)ls2->m_last_line;
+    line_offset first_line_diff = ls1->m_first_line - ls2->m_first_line;
+    if (first_line_diff.get_value () != 0)
+      return first_line_diff.get_value ();
+    return (ls1->m_last_line - ls2->m_last_line).get_value ();
   }
 
-  linenum_type m_first_line;
-  linenum_type m_last_line;
+  line_num m_first_line;
+  line_num m_last_line;
 };
 
 /* A class to control the overall layout when printing a diagnostic.
@@ -207,20 +207,20 @@ class layout
 
   expanded_location get_expanded_location (const line_span *) const;
 
-  void print_line (int row);
+  void print_line (line_num row);
 
  private:
-  bool will_show_line_p (int row) const;
-  void print_leading_fixits (int row);
-  void print_source_line (int row, const char *line, int line_width,
-			  line_bounds *lbounds_out);
-  bool should_print_annotation_line_p (int row) const;
-  void print_annotation_line (int row, const line_bounds lbounds);
-  void print_trailing_fixits (int row);
-
-  bool annotation_line_showed_range_p (int line, int start_column,
-				       int finish_column) const;
-  void show_ruler (int max_column) const;
+  bool will_show_line_p (line_num row) const;
+  void print_leading_fixits (line_num row);
+  void print_source_line (line_num row, const char *line,
+			  column_num line_width, line_bounds *lbounds_out);
+  bool should_print_annotation_line_p (line_num row) const;
+  void print_annotation_line (line_num row, const line_bounds lbounds);
+  void print_trailing_fixits (line_num row);
+
+  bool annotation_line_showed_range_p (line_num line, column_num start_column,
+				       column_num finish_column) const;
+  void show_ruler (column_num max_column) const;
 
   bool validate_fixit_hint_p (const fixit_hint *hint);
 
@@ -230,17 +230,17 @@ class layout
 
   bool
   get_state_at_point (/* Inputs.  */
-		      int row, int column,
-		      int first_non_ws, int last_non_ws,
+		      line_num row, column_num column,
+		      column_num first_non_ws, column_num last_non_ws,
 		      /* Outputs.  */
 		      point_state *out_state);
 
   int
-  get_x_bound_for_row (int row, int caret_column,
-		       int last_non_ws);
+  get_x_bound_for_row (line_num row, column_num caret_column,
+		       column_num last_non_ws);
 
   void
-  move_to_column (int *column, int dest_column);
+  move_to_column (column_num *column, column_num dest_column);
 
  private:
   diagnostic_context *m_context;
@@ -417,7 +417,7 @@ layout_range::layout_range (const expanded_location *start_exploc,
    - 'a' indicates a subsequent point *after* the range.  */
 
 bool
-layout_range::contains_point (int row, int column) const
+layout_range::contains_point (line_num row, column_num column) const
 {
   gcc_assert (m_start.m_line <= m_finish.m_line);
   /* ...but the equivalent isn't true for the columns;
@@ -478,7 +478,7 @@ layout_range::contains_point (int row, int column) const
 /* Does this layout_range contain any part of line ROW?  */
 
 bool
-layout_range::intersects_line_p (int row) const
+layout_range::intersects_line_p (line_num row) const
 {
   gcc_assert (m_start.m_line <= m_finish.m_line);
   if (row < m_start.m_line)
@@ -493,7 +493,8 @@ layout_range::intersects_line_p (int row) const
 /* A helper function for testing layout_range.  */
 
 static layout_range
-make_range (int start_line, int start_col, int end_line, int end_col)
+make_range (line_num start_line, column_num start_col,
+	    line_num end_line, column_num end_col)
 {
   const expanded_location start_exploc
     = {"test.c", start_line, start_col, NULL, false};
@@ -512,29 +513,30 @@ make_range (int start_line, int start_col, int end_line, int end_col)
 static void
 test_layout_range_for_single_point ()
 {
-  layout_range point = make_range (7, 10, 7, 10);
+  layout_range point = make_range (line_num (7), column_num (10),
+				   line_num (7), column_num (10));
 
   /* Tests for layout_range::contains_point.  */
 
   /* Before the line. */
-  ASSERT_FALSE (point.contains_point (6, 1));
+  ASSERT_FALSE (point.contains_point (line_num (6), column_num (1)));
 
   /* On the line, but before start.  */
-  ASSERT_FALSE (point.contains_point (7, 9));
+  ASSERT_FALSE (point.contains_point (line_num (7), column_num (9)));
 
   /* At the point.  */
-  ASSERT_TRUE (point.contains_point (7, 10));
+  ASSERT_TRUE (point.contains_point (line_num (7), column_num (10)));
 
   /* On the line, after the point.  */
-  ASSERT_FALSE (point.contains_point (7, 11));
+  ASSERT_FALSE (point.contains_point (line_num (7), column_num (11)));
 
   /* After the line.  */
-  ASSERT_FALSE (point.contains_point (8, 1));
+  ASSERT_FALSE (point.contains_point (line_num (8), column_num (1)));
 
   /* Tests for layout_range::intersects_line_p.  */
-  ASSERT_FALSE (point.intersects_line_p (6));
-  ASSERT_TRUE (point.intersects_line_p (7));
-  ASSERT_FALSE (point.intersects_line_p (8));
+  ASSERT_FALSE (point.intersects_line_p (line_num (6)));
+  ASSERT_TRUE (point.intersects_line_p (line_num (7)));
+  ASSERT_FALSE (point.intersects_line_p (line_num (8)));
 }
 
 /* Selftest for layout_range, where the layout_range
@@ -543,88 +545,90 @@ test_layout_range_for_single_point ()
 static void
 test_layout_range_for_single_line ()
 {
-  layout_range example_a = make_range (2, 22, 2, 38);
+  layout_range example_a = make_range (line_num (2), column_num (22),
+				       line_num (2), column_num (38));
 
   /* Tests for layout_range::contains_point.  */
 
   /* Before the line. */
-  ASSERT_FALSE (example_a.contains_point (1, 1));
+  ASSERT_FALSE (example_a.contains_point (line_num (1), column_num (1)));
 
   /* On the line, but before start.  */
-  ASSERT_FALSE (example_a.contains_point (2, 21));
+  ASSERT_FALSE (example_a.contains_point (line_num (2), column_num (21)));
 
   /* On the line, at the start.  */
-  ASSERT_TRUE (example_a.contains_point (2, 22));
+  ASSERT_TRUE (example_a.contains_point (line_num (2), column_num (22)));
 
   /* On the line, within the range.  */
-  ASSERT_TRUE (example_a.contains_point (2, 23));
+  ASSERT_TRUE (example_a.contains_point (line_num (2), column_num (23)));
 
   /* On the line, at the end.  */
-  ASSERT_TRUE (example_a.contains_point (2, 38));
+  ASSERT_TRUE (example_a.contains_point (line_num (2), column_num (38)));
 
   /* On the line, after the end.  */
-  ASSERT_FALSE (example_a.contains_point (2, 39));
+  ASSERT_FALSE (example_a.contains_point (line_num (2), column_num (39)));
 
   /* After the line.  */
-  ASSERT_FALSE (example_a.contains_point (2, 39));
+  ASSERT_FALSE (example_a.contains_point (line_num (2), column_num (39)));
 
   /* Tests for layout_range::intersects_line_p.  */
-  ASSERT_FALSE (example_a.intersects_line_p (1));
-  ASSERT_TRUE (example_a.intersects_line_p (2));
-  ASSERT_FALSE (example_a.intersects_line_p (3));
+  ASSERT_FALSE (example_a.intersects_line_p (line_num (1)));
+  ASSERT_TRUE (example_a.intersects_line_p (line_num (2)));
+  ASSERT_FALSE (example_a.intersects_line_p (line_num (3)));
 }
 
-/* Selftest for layout_range, where the layout_range
+/* Selftest for layout_range), column_num (where the layout_range
    is the multi-line range shown as "Example B" above.  */
 
 static void
 test_layout_range_for_multiple_lines ()
 {
-  layout_range example_b = make_range (3, 14, 5, 8);
+  layout_range example_b = make_range (line_num (3), column_num (14),
+				       line_num (5), column_num (8));
 
   /* Tests for layout_range::contains_point.  */
 
   /* Before first line. */
-  ASSERT_FALSE (example_b.contains_point (1, 1));
+  ASSERT_FALSE (example_b.contains_point (line_num (1), column_num (1)));
 
   /* On the first line, but before start.  */
-  ASSERT_FALSE (example_b.contains_point (3, 13));
+  ASSERT_FALSE (example_b.contains_point (line_num (3), column_num (13)));
 
   /* At the start.  */
-  ASSERT_TRUE (example_b.contains_point (3, 14));
+  ASSERT_TRUE (example_b.contains_point (line_num (3), column_num (14)));
 
   /* On the first line, within the range.  */
-  ASSERT_TRUE (example_b.contains_point (3, 15));
+  ASSERT_TRUE (example_b.contains_point (line_num (3), column_num (15)));
 
   /* On an interior line.
      The column number should not matter; try various boundary
      values.  */
-  ASSERT_TRUE (example_b.contains_point (4, 1));
-  ASSERT_TRUE (example_b.contains_point (4, 7));
-  ASSERT_TRUE (example_b.contains_point (4, 8));
-  ASSERT_TRUE (example_b.contains_point (4, 9));
-  ASSERT_TRUE (example_b.contains_point (4, 13));
-  ASSERT_TRUE (example_b.contains_point (4, 14));
-  ASSERT_TRUE (example_b.contains_point (4, 15));
+  ASSERT_TRUE (example_b.contains_point (line_num (4), column_num (1)));
+  ASSERT_TRUE (example_b.contains_point (line_num (4), column_num (7)));
+  ASSERT_TRUE (example_b.contains_point (line_num (4), column_num (8)));
+  ASSERT_TRUE (example_b.contains_point (line_num (4), column_num (9)));
+  ASSERT_TRUE (example_b.contains_point (line_num (4), column_num (13)));
+  ASSERT_TRUE (example_b.contains_point (line_num (4), column_num (14)));
+  ASSERT_TRUE (example_b.contains_point (line_num (4), column_num (15)));
 
   /* On the final line, before the end.  */
-  ASSERT_TRUE (example_b.contains_point (5, 7));
+  ASSERT_TRUE (example_b.contains_point (line_num (5), column_num (7)));
 
   /* On the final line, at the end.  */
-  ASSERT_TRUE (example_b.contains_point (5, 8));
+  ASSERT_TRUE (example_b.contains_point (line_num (5), column_num (8)));
 
   /* On the final line, after the end.  */
-  ASSERT_FALSE (example_b.contains_point (5, 9));
+  ASSERT_FALSE (example_b.contains_point (line_num (5), column_num (9)));
 
   /* After the line.  */
-  ASSERT_FALSE (example_b.contains_point (6, 1));
+  ASSERT_FALSE (example_b.contains_point (line_num (6), column_num (1)));
 
   /* Tests for layout_range::intersects_line_p.  */
-  ASSERT_FALSE (example_b.intersects_line_p (2));
-  ASSERT_TRUE (example_b.intersects_line_p (3));
-  ASSERT_TRUE (example_b.intersects_line_p (4));
-  ASSERT_TRUE (example_b.intersects_line_p (5));
-  ASSERT_FALSE (example_b.intersects_line_p (6));
+  ASSERT_FALSE (example_b.intersects_line_p (line_num (2)));
+  ASSERT_TRUE (example_b.intersects_line_p (line_num (3)));
+  ASSERT_TRUE (example_b.intersects_line_p (line_num (4)));
+  ASSERT_TRUE (example_b.intersects_line_p (line_num (5)));
+  ASSERT_FALSE (example_b.intersects_line_p (line_num (6)));
 }
 
 #endif /* #if CHECKING_P */
@@ -820,10 +824,10 @@ layout::layout (diagnostic_context * context,
      will be adjusted accordingly.  */
   size_t max_width = m_context->m_caret_max_width;
   char_span line = location_get_source_line (m_exploc.file, m_exploc.line);
-  if (line && (size_t)m_exploc.column <= line.length ())
+  if (line && as_size_t (m_exploc.column) <= line.length ())
     {
-      size_t right_margin = CARET_LINE_MARGIN;
-      size_t column = m_exploc.column;
+      column_num right_margin (CARET_LINE_MARGIN);
+      column_num column = m_exploc.column;
       right_margin = MIN (line.length () - column, right_margin);
       right_margin = max_width - right_margin;
       if (line.length () >= max_width && column > right_margin)
@@ -935,7 +939,7 @@ layout::maybe_add_location_range (const location_range *loc_range,
 /* Return true iff ROW is within one of the line spans for this layout.  */
 
 bool
-layout::will_show_line_p (int row) const
+layout::will_show_line_p (line_num row) const
 {
   for (int line_span_idx = 0; line_span_idx < get_num_line_spans ();
        line_span_idx++)
@@ -960,7 +964,7 @@ layout::print_heading_for_line_span_index_p (int line_span_idx) const
 
   /* We also do it for the initial span if the primary location of the
      diagnostic is in a different span.  */
-  if (m_exploc.line > (int)get_line_span (0)->m_last_line)
+  if (m_exploc.line > get_line_span (0)->m_last_line)
     return true;
 
   return false;
@@ -1098,7 +1102,7 @@ layout::calculate_line_spans ()
       line_span *current = &m_line_spans[m_line_spans.length () - 1];
       const line_span *next = &tmp_spans[i];
       gcc_assert (next->m_first_line >= current->m_first_line);
-      if (next->m_first_line <= current->m_last_line + 1)
+      if (next->m_first_line <= current->m_last_line + line_num (1))
 	{
 	  /* We can merge them. */
 	  if (next->m_last_line > current->m_last_line)
@@ -1123,7 +1127,7 @@ layout::calculate_line_spans ()
       /* The spans must be ordered.  */
       gcc_assert (prev->m_first_line < next->m_first_line);
       /* There must be a gap of at least one line between separate spans.  */
-      gcc_assert ((prev->m_last_line + 1) < next->m_first_line);
+      gcc_assert ((prev->m_last_line + line_num (1)) < next->m_first_line);
     }
 }
 
@@ -1133,8 +1137,8 @@ layout::calculate_line_spans ()
    is its width.  */
 
 void
-layout::print_source_line (int row, const char *line, int line_width,
-			   line_bounds *lbounds_out)
+layout::print_source_line (line_num row, const char *line,
+			   column_num line_width, line_bounds *lbounds_out)
 {
   m_colorizer.set_normal_text ();
 
@@ -1145,9 +1149,9 @@ layout::print_source_line (int row, const char *line, int line_width,
   line += m_x_offset;
 
   pp_space (m_pp);
-  int first_non_ws = INT_MAX;
-  int last_non_ws = 0;
-  int column;
+  column_num first_non_ws (INT_MAX);
+  column_num last_non_ws (0);
+  column_num column;
   for (column = 1 + m_x_offset; column <= line_width; column++)
     {
       /* Assuming colorization is enabled for the caret and underline
@@ -1180,7 +1184,7 @@ layout::print_source_line (int row, const char *line, int line_width,
       if (c != ' ')
 	{
 	  last_non_ws = column;
-	  if (first_non_ws == INT_MAX)
+	  if (first_non_ws == column_num (INT_MAX))
 	    first_non_ws = column;
 	}
       pp_character (m_pp, c);
@@ -1196,7 +1200,7 @@ layout::print_source_line (int row, const char *line, int line_width,
    i.e. if any of m_layout_ranges contains ROW.  */
 
 bool
-layout::should_print_annotation_line_p (int row) const
+layout::should_print_annotation_line_p (line_num row) const
 {
   layout_range *range;
   int i;
@@ -1210,13 +1214,13 @@ layout::should_print_annotation_line_p (int row) const
    source line.  */
 
 void
-layout::print_annotation_line (int row, const line_bounds lbounds)
+layout::print_annotation_line (line_num row, const line_bounds lbounds)
 {
-  int x_bound = get_x_bound_for_row (row, m_exploc.column,
-				     lbounds.m_last_non_ws);
+  column_num x_bound = get_x_bound_for_row (row, m_exploc.column,
+					    lbounds.m_last_non_ws);
 
   pp_space (m_pp);
-  for (int column = 1 + m_x_offset; column < x_bound; column++)
+  for (column_num column = 1 + m_x_offset; column < x_bound; column++)
     {
       bool in_range_p;
       point_state state;
@@ -1258,7 +1262,7 @@ layout::print_annotation_line (int row, const line_bounds lbounds)
    itself, with a leading '+'.  */
 
 void
-layout::print_leading_fixits (int row)
+layout::print_leading_fixits (line_num row)
 {
   for (unsigned int i = 0; i < m_fixit_hints.length (); i++)
     {
@@ -1296,8 +1300,8 @@ layout::print_leading_fixits (int row)
    the exact range from START_COLUMN to FINISH_COLUMN.  */
 
 bool
-layout::annotation_line_showed_range_p (int line, int start_column,
-					int finish_column) const
+layout::annotation_line_showed_range_p (line_num line, column_num start_column,
+					column_num finish_column) const
 {
   layout_range *range;
   int i;
@@ -1396,10 +1400,11 @@ layout::annotation_line_showed_range_p (int line, int start_column,
 
 struct column_range
 {
-  column_range (int start_, int finish_) : start (start_), finish (finish_)
+  column_range (column_num start_, column_num finish_)
+  : start (start_), finish (finish_)
   {
     /* We must have either a range, or an insertion.  */
-    gcc_assert (start <= finish || finish == start - 1);
+    gcc_assert (start <= finish || finish == start - column_num (1));
   }
 
   bool operator== (const column_range &other) const
@@ -1407,8 +1412,8 @@ struct column_range
     return start == other.start && finish == other.finish;
   }
 
-  int start;
-  int finish;
+  column_num start;
+  column_num finish;
 };
 
 /* Get the range of columns that HINT would affect.  */
@@ -1416,8 +1421,9 @@ struct column_range
 static column_range
 get_affected_columns (const fixit_hint *hint)
 {
-  int start_column = LOCATION_COLUMN (hint->get_start_loc ());
-  int finish_column = LOCATION_COLUMN (hint->get_next_loc ()) - 1;
+  column_num start_column = LOCATION_COLUMN (hint->get_start_loc ());
+  column_num finish_column
+    = LOCATION_COLUMN (hint->get_next_loc ()) - column_num (1);
 
   return column_range (start_column, finish_column);
 }
@@ -1427,8 +1433,8 @@ get_affected_columns (const fixit_hint *hint)
 static column_range
 get_printed_columns (const fixit_hint *hint)
 {
-  int start_column = LOCATION_COLUMN (hint->get_start_loc ());
-  int final_hint_column = start_column + hint->get_length () - 1;
+  column_num start_column = LOCATION_COLUMN (hint->get_start_loc ());
+  column_num final_hint_column = start_column + hint->get_length () - 1;
   if (hint->insertion_p ())
     {
       return column_range (start_column, final_hint_column);
@@ -1527,7 +1533,7 @@ correction::ensure_terminated ()
 
 struct line_corrections
 {
-  line_corrections (const char *filename, int row)
+  line_corrections (const char *filename, line_num row)
   : m_filename (filename), m_row (row)
   {}
   ~line_corrections ();
@@ -1554,7 +1560,7 @@ line_corrections::~line_corrections ()
 
 struct source_line
 {
-  source_line (const char *filename, int line);
+  source_line (const char *filename, line_num line);
 
   char_span as_span () { return char_span (chars, width); }
 
@@ -1564,7 +1570,7 @@ struct source_line
 
 /* source_line's ctor.  */
 
-source_line::source_line (const char *filename, int line)
+source_line::source_line (const char *filename, line_num line)
 {
   char_span span = location_get_source_line (filename, line);
   chars = span.get_buffer ();
@@ -1651,7 +1657,7 @@ line_corrections::add_hint (const fixit_hint *hint)
    in layout::print_leading_fixits.  */
 
 void
-layout::print_trailing_fixits (int row)
+layout::print_trailing_fixits (line_num row)
 {
   /* Build a list of correction instances for the line,
      potentially consolidating hints (for the sake of readability).  */
@@ -1671,7 +1677,7 @@ layout::print_trailing_fixits (int row)
   /* Now print the corrections.  */
   unsigned i;
   correction *c;
-  int column = m_x_offset;
+  column_num column = m_x_offset;
 
   FOR_EACH_VEC_ELT (corrections.m_corrections, i, c)
     {
@@ -1679,7 +1685,7 @@ layout::print_trailing_fixits (int row)
       if (c->insertion_p ())
 	{
 	  /* This assumes the insertion just affects one line.  */
-	  int start_column = c->m_printed_columns.start;
+	  column_num start_column = c->m_printed_columns.start;
 	  move_to_column (&column, start_column);
 	  m_colorizer.set_fixit_insert ();
 	  pp_string (m_pp, c->m_text);
@@ -1692,8 +1698,8 @@ layout::print_trailing_fixits (int row)
 	     annotation line, then print an extra underline to
 	     indicate exactly what is being replaced.
 	     Always show it for removals.  */
-	  int start_column = c->m_affected_columns.start;
-	  int finish_column = c->m_affected_columns.finish;
+	  column_num start_column = c->m_affected_columns.start;
+	  column_num finish_column = c->m_affected_columns.finish;
 	  if (!annotation_line_showed_range_p (row, start_column,
 					       finish_column)
 	      || c->m_len == 0)
@@ -1738,8 +1744,8 @@ layout::print_newline ()
 
 bool
 layout::get_state_at_point (/* Inputs.  */
-			    int row, int column,
-			    int first_non_ws, int last_non_ws,
+			    line_num row, column_num column,
+			    column_num first_non_ws, column_num last_non_ws,
 			    /* Outputs.  */
 			    point_state *out_state)
 {
@@ -1783,8 +1789,8 @@ layout::get_state_at_point (/* Inputs.  */
    character of source (as determined when printing the source line).  */
 
 int
-layout::get_x_bound_for_row (int row, int caret_column,
-			     int last_non_ws_column)
+layout::get_x_bound_for_row (line_num row, column_num caret_column,
+			     column_num last_non_ws_column)
 {
   int result = caret_column + 1;
 
@@ -1819,7 +1825,7 @@ layout::get_x_bound_for_row (int row, int caret_column,
    and updating *COLUMN.  */
 
 void
-layout::move_to_column (int *column, int dest_column)
+layout::move_to_column (column_num *column, column_num dest_column)
 {
   /* Start a new line if we need to.  */
   if (*column > dest_column)
@@ -1839,13 +1845,14 @@ layout::move_to_column (int *column, int dest_column)
    (after the 1-column indent).  */
 
 void
-layout::show_ruler (int max_column) const
+layout::show_ruler (column_num max_column) const
 {
   /* Hundreds.  */
-  if (max_column > 99)
+  if (max_column > column_num (99))
     {
       pp_space (m_pp);
-      for (int column = 1 + m_x_offset; column <= max_column; column++)
+      for (column_num::value_t column = 1 + m_x_offset; column <= max_column;
+	   column++)
 	if (column % 10 == 0)
 	  pp_character (m_pp, '0' + (column / 100) % 10);
 	else
@@ -1855,7 +1862,8 @@ layout::show_ruler (int max_column) const
 
   /* Tens.  */
   pp_space (m_pp);
-  for (int column = 1 + m_x_offset; column <= max_column; column++)
+  for (column_num::value_t column = 1 + m_x_offset; column <= max_column;
+       column++)
     if (column % 10 == 0)
       pp_character (m_pp, '0' + (column / 10) % 10);
     else
@@ -1864,7 +1872,8 @@ layout::show_ruler (int max_column) const
 
   /* Units.  */
   pp_space (m_pp);
-  for (int column = 1 + m_x_offset; column <= max_column; column++)
+  for (column_num::value_t column = 1 + m_x_offset; column <= max_column;
+       column++)
     pp_character (m_pp, '0' + (column % 10));
   pp_newline (m_pp);
 }
@@ -1874,7 +1883,7 @@ layout::show_ruler (int max_column) const
    consisting of any caret/underlines, then any fixits.
    If the source line can't be read, print nothing.  */
 void
-layout::print_line (int row)
+layout::print_line (line_num row)
 {
   char_span line = location_get_source_line (m_exploc.file, row);
   if (!line)
@@ -1952,8 +1961,8 @@ diagnostic_show_locus (diagnostic_context * context,
 	  expanded_location exploc = layout.get_expanded_location (line_span);
 	  context->m_start_span (context, exploc);
 	}
-      int last_line = line_span->get_last_line ();
-      for (int row = line_span->get_first_line (); row <= last_line; row++)
+      line_num last_line = line_span->get_last_line ();
+      for (line_num row = line_span->get_first_line (); row <= last_line; row++)
 	layout.print_line (row);
     }
 
@@ -2311,8 +2320,8 @@ test_diagnostic_show_locus_one_liner (const line_table_case &case_)
     return;
 
   ASSERT_STREQ (tmp.get_filename (), LOCATION_FILE (line_end));
-  ASSERT_EQ (1, LOCATION_LINE (line_end));
-  ASSERT_EQ (16, LOCATION_COLUMN (line_end));
+  ASSERT_EQ (line_num (1), LOCATION_LINE (line_end));
+  ASSERT_EQ (column_num (16), LOCATION_COLUMN (line_end));
 
   test_one_liner_simple_caret ();
   test_one_liner_caret_and_range ();
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 0e57d2b..a89ac97 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -393,8 +393,10 @@ static inline bool
 diagnostic_same_line (const diagnostic_context *context,
 		       expanded_location s1, expanded_location s2)
 {
-  return s2.column && s1.line == s2.line 
-    && context->m_caret_max_width - CARET_LINE_MARGIN > abs (s1.column - s2.column);
+  return (s2.column > column_num (0)
+	  && s1.line == s2.line 
+	  && (context->m_caret_max_width - CARET_LINE_MARGIN
+	      > abs ((s1.column - s2.column).get_value ())));
 }
 
 extern const char *diagnostic_get_color_for_kind (diagnostic_t kind);
diff --git a/gcc/final.c b/gcc/final.c
index a301903..34a0d10 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -116,10 +116,10 @@ static rtx_insn *debug_insn;
 rtx_insn *current_output_insn;
 
 /* Line number of last NOTE.  */
-static int last_linenum;
+static line_num last_linenum;
 
 /* Column number of last NOTE.  */
-static int last_columnnum;
+static column_num  last_columnnum;
 
 /* Last discriminator written to assembly.  */
 static int last_discriminator;
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 7460586..fde0caa 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1809,7 +1809,7 @@ gimple_filename (const gimple *stmt)
 static inline int
 gimple_lineno (const gimple *stmt)
 {
-  return LOCATION_LINE (gimple_location (stmt));
+  return LOCATION_LINE (gimple_location (stmt)).get_value ();
 }
 
 
@@ -4809,7 +4809,7 @@ get_lineno (const gimple *stmt)
   if (loc == UNKNOWN_LOCATION)
     return -1;
 
-  return LOCATION_LINE (loc);
+  return LOCATION_LINE (loc).get_value ();
 }
 
 /* Return a pointer to the body for the OMP statement GS.  */
diff --git a/gcc/input.h b/gcc/input.h
index b0aea87..d1791fb 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -82,7 +82,8 @@ class char_span
   size_t m_n_elts;
 };
 
-extern char_span location_get_source_line (const char *file_path, int line);
+extern char_span location_get_source_line (const char *file_path,
+					   line_num line);
 
 extern bool location_missing_trailing_newline (const char *file_path);
 
diff --git a/libcpp/directives-only.c b/libcpp/directives-only.c
index de67308..2c25be8 100644
--- a/libcpp/directives-only.c
+++ b/libcpp/directives-only.c
@@ -41,7 +41,7 @@ _cpp_preprocess_dir_only (cpp_reader *pfile,
   const unsigned char *cur, *base, *next_line, *rlimit;
   cppchar_t c, last_c;
   unsigned flags;
-  linenum_type lines;
+  line_num::value_t lines;
   int col;
   source_location loc;
 
diff --git a/libcpp/directives.c b/libcpp/directives.c
index bf13ada..fdc1344 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -101,7 +101,7 @@ static const char *parse_include (cpp_reader *, int *, const cpp_token ***,
 				  source_location *);
 static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *);
 static unsigned int read_flag (cpp_reader *, unsigned int);
-static bool strtolinenum (const uchar *, size_t, linenum_type *, bool *);
+static bool strtolinenum (const uchar *, size_t, line_num *, bool *);
 static void do_diagnostic (cpp_reader *, int, int, int);
 static cpp_hashnode *lex_macro_node (cpp_reader *, bool);
 static int undefine_macros (cpp_reader *, cpp_hashnode *, void *);
@@ -921,10 +921,10 @@ read_flag (cpp_reader *pfile, unsigned int last)
    number was well-formed, true if not. WRAPPED is set to true if the
    number did not fit into 'unsigned long'.  */
 static bool
-strtolinenum (const uchar *str, size_t len, linenum_type *nump, bool *wrapped)
+strtolinenum (const uchar *str, size_t len, line_num *nump, bool *wrapped)
 {
-  linenum_type reg = 0;
-  linenum_type reg_prev = 0;
+  line_num::value_t reg = 0;
+  line_num::value_t reg_prev = 0;
 
   uchar c;
   *wrapped = false;
@@ -939,7 +939,7 @@ strtolinenum (const uchar *str, size_t len, linenum_type *nump, bool *wrapped)
 	*wrapped = true;
       reg_prev = reg;
     }
-  *nump = reg;
+  *nump = line_num (reg);
   return false;
 }
 
@@ -958,10 +958,10 @@ do_line (cpp_reader *pfile)
   unsigned char map_sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (map);
   const cpp_token *token;
   const char *new_file = ORDINARY_MAP_FILE_NAME (map);
-  linenum_type new_lineno;
+  line_num new_lineno;
 
   /* C99 raised the minimum limit on #line numbers.  */
-  linenum_type cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767;
+  line_num cap = line_num (CPP_OPTION (pfile, c99) ? 2147483647 : 32767);
   bool wrapped;
 
   /* #line commands expand macros.  */
@@ -979,7 +979,10 @@ do_line (cpp_reader *pfile)
       return;
     }
 
-  if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || new_lineno > cap || wrapped))
+  if (CPP_PEDANTIC (pfile)
+      && (new_lineno == line_num (0)
+	  || new_lineno > cap
+	  || wrapped))
     cpp_error (pfile, CPP_DL_PEDWARN, "line number out of range");
   else if (wrapped)
     cpp_error (pfile, CPP_DL_WARNING, "line number out of range");
@@ -1016,7 +1019,7 @@ do_linemarker (cpp_reader *pfile)
   const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (line_table);
   const cpp_token *token;
   const char *new_file = ORDINARY_MAP_FILE_NAME (map);
-  linenum_type new_lineno;
+  line_num new_lineno;
   unsigned int new_sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (map);
   enum lc_reason reason = LC_RENAME_VERBATIM;
   int flag;
@@ -1117,7 +1120,7 @@ do_linemarker (cpp_reader *pfile)
    and zero otherwise.  */
 void
 _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason,
-		     const char *to_file, linenum_type file_line,
+		     const char *to_file, line_num file_line,
 		     unsigned int sysp)
 {
   linemap_assert (reason != LC_ENTER_MACRO);
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index f6242fc..f9f6238 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -26,6 +26,31 @@ along with this program; see the file COPYING3.  If not see
 #define GTY(x) /* nothing */
 #endif
 
+#if CHECKING_P && (GCC_VERSION >= 2007)
+
+/* Assertion macro to be used in line-map code.  */
+#define linemap_assert(EXPR)                  \
+  do {                                                \
+    if (! (EXPR))                             \
+      abort ();                                       \
+  } while (0)
+
+/* Assert that becomes a conditional expression when checking is disabled at
+   compilation time.  Use this for conditions that should not happen but if
+   they happen, it is better to handle them gracefully rather than crash
+   randomly later.
+   Usage:
+
+   if (linemap_assert_fails(EXPR)) handle_error(); */
+#define linemap_assert_fails(EXPR) __extension__ \
+  ({linemap_assert (EXPR); false;})
+
+#else
+/* Include EXPR, so that unused variable warnings do not occur.  */
+#define linemap_assert(EXPR) ((void)(0 && (EXPR)))
+#define linemap_assert_fails(EXPR) (! (EXPR))
+#endif
+
 /* Both gcc and emacs number source *lines* starting at 1, but
    they have differing conventions for *columns*.
 
@@ -46,8 +71,131 @@ along with this program; see the file COPYING3.  If not see
 
    i.e. "3:1:" in GCC corresponds to "(3, 0)" in Emacs.  */
 
+template <typename Traits>
+class named_type
+{
+ public:
+  typedef typename Traits::value_t value_t;
+
+  // do-nothing default ctor
+  named_type () {}
+
+  explicit named_type (value_t value) : m_value (value) {}
+
+  value_t get_value () const { return m_value; }
+  void set_value (value_t value) { m_value = value; }
+
+ private:
+  value_t m_value;
+};
+
+template <typename T>
+inline named_type<T>
+operator+ (named_type<T> a, named_type<T> b)
+{
+  return named_type<T> (a.get_value () + b.get_value ());
+}
+
+template <typename T>
+inline named_type<T>&
+operator+= (named_type<T> &a, named_type<T> b)
+{
+  a.set_value (a.get_value () + b.get_value ());
+  return a;
+}
+
+#if 0
+template <typename T>
+inline int
+operator- (named_type<T> a, named_type<T> b)
+{
+  return a.get_value () - b.get_value ();
+}
+#endif
+
+template <typename T>
+inline bool
+operator< (named_type<T> a, named_type<T> b)
+{
+  return a.get_value () < b.get_value ();
+}
+
+template <typename T>
+inline bool
+operator<= (named_type<T> a, named_type<T> b)
+{
+  return a.get_value () <= b.get_value ();
+}
+
+template <typename T>
+inline bool
+operator== (named_type<T> a, named_type<T> b)
+{
+  return a.get_value () == b.get_value ();
+}
+
+template <typename T>
+inline bool
+operator> (named_type<T> a, named_type<T> b)
+{
+  return a.get_value () > b.get_value ();
+}
+
+template <typename T>
+inline bool
+operator>= (named_type<T> a, named_type<T> b)
+{
+  return a.get_value () > b.get_value ();
+}
+
+template <typename T>
+inline bool
+operator!= (named_type<T> a, named_type<T> b)
+{
+  return a.get_value () != b.get_value ();
+}
+
+/* Ideally we'd use a "using line_num =" here, but C++98.
+   Also, we could have a dummy struct for expressing uniqueness and do it as a
+   one-liner.
+   Sadly, gengtype can't cope with that.  */
+
 /* The type of line numbers.  */
-typedef unsigned int linenum_type;
+struct line_num_traits { typedef unsigned int value_t; };
+typedef named_type<line_num_traits> line_num;
+
+/* The type of column numbers.  */
+struct column_num_traits { typedef unsigned int value_t; };
+typedef named_type<column_num_traits> column_num;
+
+/* Explicit conversion of column_num to size_t (for use e.g. when comparing
+   with a buffer of line content).  */
+inline size_t
+as_size_t (column_num col)
+{
+  return (size_t)col.get_value ();
+}
+
+/* A type for differences between line numbers.  */
+struct line_offset_traits { typedef int value_t; };
+typedef named_type<line_offset_traits> line_offset;
+
+/* A type for differences between column numbers.  */
+struct column_offset_traits { typedef int value_t; };
+typedef named_type<column_offset_traits> column_offset;
+
+inline line_offset
+operator- (line_num a, line_num b)
+{
+  return line_offset((int)a.get_value () - (int)b.get_value ());
+}
+
+inline column_offset
+operator- (column_num a, column_num b)
+{
+  return column_offset((int)a.get_value () - (int)b.get_value ());
+}
+
 
 /* Reason for creating a new line map with linemap_add.  LC_ENTER is
    when including a new file, e.g. a #include directive in C.
@@ -386,7 +534,7 @@ struct GTY((tag ("0"), desc ("%h.reason == LC_ENTER_MACRO ? 2 : 1"))) line_map {
    The highest possible source location is MAX_SOURCE_LOCATION.  */
 struct GTY((tag ("1"))) line_map_ordinary : public line_map {
   const char *to_file;
-  linenum_type to_line;
+  line_num to_line;
 
   /* An index into the set that gives the line mapping at whose end
      the current one was included.  File(s) at the bottom of the
@@ -417,6 +565,14 @@ struct GTY((tag ("1"))) line_map_ordinary : public line_map {
      |                         |    (e.g. 7)           |   (e.g. 5)        |
      +-------------------------+-----------------------+-------------------+ */
   unsigned int m_range_bits : 8;
+
+  /* FIXME (effectively column 0 == "the whole line").  */
+  source_location get_line (line_num line) const
+  {
+    linemap_assert (line >= to_line);
+    return start_location + (((unsigned int)(line - to_line).get_value ())
+			     << m_column_and_range_bits);
+  }
 };
 
 /* This is the highest possible source location encoded within an
@@ -503,31 +659,6 @@ struct GTY((tag ("2"))) line_map_macro : public line_map {
   source_location expansion;
 };
 
-#if CHECKING_P && (GCC_VERSION >= 2007)
-
-/* Assertion macro to be used in line-map code.  */
-#define linemap_assert(EXPR)                  \
-  do {                                                \
-    if (! (EXPR))                             \
-      abort ();                                       \
-  } while (0)
-
-/* Assert that becomes a conditional expression when checking is disabled at
-   compilation time.  Use this for conditions that should not happen but if
-   they happen, it is better to handle them gracefully rather than crash
-   randomly later.
-   Usage:
-
-   if (linemap_assert_fails(EXPR)) handle_error(); */
-#define linemap_assert_fails(EXPR) __extension__ \
-  ({linemap_assert (EXPR); false;})
-
-#else
-/* Include EXPR, so that unused variable warnings do not occur.  */
-#define linemap_assert(EXPR) ((void)(0 && (EXPR)))
-#define linemap_assert_fails(EXPR) (! (EXPR))
-#endif
-
 /* Return TRUE if MAP encodes locations coming from a macro
    replacement-list at macro expansion point.  */
 bool
@@ -584,7 +715,7 @@ MAP_START_LOCATION (const line_map *map)
 
 /* Get the starting line number of ordinary map MAP.  */
 
-inline linenum_type
+inline line_num
 ORDINARY_MAP_STARTING_LINE_NUMBER (const line_map_ordinary *ord_map)
 {
   return ord_map->to_line;
@@ -1062,7 +1193,7 @@ extern void linemap_check_files_exited (struct line_maps *);
    the highest_location).  */
 
 extern source_location linemap_line_start
-(struct line_maps *set, linenum_type to_line,  unsigned int max_column_hint);
+(struct line_maps *set, line_num to_line,  unsigned int max_column_hint);
 
 /* Add a mapping of logical source line to physical source file and
    line number. This function creates an "ordinary map", which is a
@@ -1079,7 +1210,7 @@ extern source_location linemap_line_start
    maps, so any stored line_map pointers should not be used.  */
 extern const struct line_map *linemap_add
   (struct line_maps *, enum lc_reason, unsigned int sysp,
-   const char *to_file, linenum_type to_line);
+   const char *to_file, line_num to_line);
 
 /* Given a logical source location, returns the map which the
    corresponding (source file, line, column) triplet can be deduced
@@ -1133,19 +1264,22 @@ extern source_location linemap_macro_map_loc_unwind_toward_spelling
 const source_location RESERVED_LOCATION_COUNT = 2;
 
 /* Converts a map and a source_location to source line.  */
-inline linenum_type
+inline line_num
 SOURCE_LINE (const line_map_ordinary *ord_map, source_location loc)
 {
-  return ((loc - ord_map->start_location)
-	  >> ord_map->m_column_and_range_bits) + ord_map->to_line;
+  return line_num((loc - ord_map->start_location)
+		  >> ord_map->m_column_and_range_bits) + ord_map->to_line;
 }
 
 /* Convert a map and source_location to source column number.  */
-inline linenum_type
+inline column_num
 SOURCE_COLUMN (const line_map_ordinary *ord_map, source_location loc)
 {
-  return ((loc - ord_map->start_location)
-	  & ((1 << ord_map->m_column_and_range_bits) - 1)) >> ord_map->m_range_bits;
+  return column_num (
+		     (
+		      (loc - ord_map->start_location)
+		      & ((1 << ord_map->m_column_and_range_bits) - 1))
+		     >> ord_map->m_range_bits);
 }
 
 /* Return the location of the last source line within an ordinary
@@ -1162,7 +1296,7 @@ LAST_SOURCE_LINE_LOCATION (const line_map_ordinary *map)
 /* Returns the last source line number within an ordinary map.  This
    is the (last) line of the #include, or other directive, that caused
    a map change.  */
-inline linenum_type
+inline line_num
 LAST_SOURCE_LINE (const line_map_ordinary *map)
 {
   return SOURCE_LINE (map, LAST_SOURCE_LINE_LOCATION (map));
@@ -1170,7 +1304,7 @@ LAST_SOURCE_LINE (const line_map_ordinary *map)
 
 /* Return the last column number within an ordinary map.  */
 
-inline linenum_type
+inline column_num
 LAST_SOURCE_COLUMN (const line_map_ordinary *map)
 {
   return SOURCE_COLUMN (map, LAST_SOURCE_LINE_LOCATION (map));
@@ -1207,7 +1341,7 @@ linemap_position_for_column (struct line_maps *, unsigned int);
 source_location
 linemap_position_for_line_and_column (line_maps *set,
 				      const line_map_ordinary *,
-				      linenum_type, unsigned int);
+				      line_num, column_num);
 
 /* Encode and return a source_location starting from location LOC and
    shifting it by OFFSET columns.  This function does not support
@@ -1215,7 +1349,7 @@ linemap_position_for_line_and_column (line_maps *set,
 source_location
 linemap_position_for_loc_and_offset (struct line_maps *set,
 				     source_location loc,
-				     unsigned int offset);
+				     column_num offset);
 
 /* Return the file this map is for.  */
 inline const char *
@@ -1225,7 +1359,7 @@ LINEMAP_FILE (const line_map_ordinary *ord_map)
 }
 
 /* Return the line number this map started encoding location from.  */
-inline linenum_type
+inline line_num
 LINEMAP_LINE (const line_map_ordinary *ord_map)
 {
   return ord_map->to_line;
@@ -1266,9 +1400,9 @@ typedef struct
   const char *file;
 
   /* The line-location in the source file.  */
-  int line;
+  line_num line;
 
-  int column;
+  column_num column;
 
   void *data;
 
@@ -1739,7 +1873,7 @@ class fixit_hint
 	      const char *new_content);
   ~fixit_hint () { free (m_bytes); }
 
-  bool affects_line_p (const char *file, int line) const;
+  bool affects_line_p (const char *file, line_num line) const;
   source_location get_start_loc () const { return m_start; }
   source_location get_next_loc () const { return m_next_loc; }
   bool maybe_append (source_location start,
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 782d8e6..de1ac84 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -70,8 +70,8 @@ struct cset_converter
     const struct line_maps *line_table = PFILE->line_table; \
     const struct line_map_ordinary *map = \
       LINEMAPS_LAST_ORDINARY_MAP (line_table); \
-    linenum_type line = SOURCE_LINE (map, line_table->highest_line); \
-    linemap_line_start (PFILE->line_table, line + 1, COLS_HINT); \
+    line_num line = SOURCE_LINE (map, line_table->highest_line); \
+    linemap_line_start (PFILE->line_table, line + line_num (1), COLS_HINT); \
   } while (0)
 
 /* Maximum nesting of cpp_buffers.  We use a static limit, partly for
@@ -700,7 +700,7 @@ extern int _cpp_do__Pragma (cpp_reader *, source_location);
 extern void _cpp_init_directives (cpp_reader *);
 extern void _cpp_init_internal_pragmas (cpp_reader *);
 extern void _cpp_do_file_change (cpp_reader *, enum lc_reason, const char *,
-				 linenum_type, unsigned int);
+				 line_num, unsigned int);
 extern void _cpp_pop_buffer (cpp_reader *);
 extern char *_cpp_bracket_include (cpp_reader *);
 
@@ -881,8 +881,8 @@ source_location linemap_add_macro_token (const line_map_macro *,
    LOCATION is the location of token that is part of the
    expansion-list of a macro expansion return the line number of the
    macro expansion point.  */
-int linemap_get_expansion_line (struct line_maps *,
-				source_location);
+line_num linemap_get_expansion_line (struct line_maps *,
+				     source_location);
 
 /* Return the path of the file corresponding to source code location
    LOCATION.
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index 677acd6..9848e9c 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -471,7 +471,7 @@ new_linemap (struct line_maps *set,
 
 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)
+	     unsigned int sysp, const char *to_file, line_num to_line)
 {
   /* Generate a start_location above the current highest_location.
      If possible, make the low range bits be zero.  */
@@ -692,15 +692,15 @@ linemap_add_macro_token (const line_map_macro *map,
    the highest_location).  */
 
 source_location
-linemap_line_start (struct line_maps *set, linenum_type to_line,
+linemap_line_start (struct line_maps *set, line_num to_line,
 		    unsigned int max_column_hint)
 {
   line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
   source_location highest = set->highest_location;
   source_location r;
-  linenum_type last_line =
+  line_num last_line =
     SOURCE_LINE (map, set->highest_line);
-  int line_delta = to_line - last_line;
+  int line_delta = (to_line - last_line).get_value ();
   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;
@@ -749,7 +749,8 @@ linemap_line_start (struct 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)
+	      >= column_num (1U << (column_bits - range_bits)))
 	  || range_bits < map->m_range_bits)
 	map = linemap_check_ordinary
 	        (const_cast <line_map *>
@@ -759,9 +760,7 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
 				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));
+      r = map->get_line(to_line);
     }
   else
     r = set->highest_line + (line_delta << map->m_column_and_range_bits);
@@ -844,16 +843,14 @@ linemap_position_for_column (struct line_maps *set, unsigned int to_column)
 source_location
 linemap_position_for_line_and_column (line_maps *set,
 				      const line_map_ordinary *ord_map,
-				      linenum_type line,
-				      unsigned column)
+				      line_num line,
+				      column_num column)
 {
   linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line);
 
-  source_location r = MAP_START_LOCATION (ord_map);
-  r += ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map))
-	<< ord_map->m_column_and_range_bits);
+  source_location r = ord_map->get_line (line);
   if (r <= LINE_MAP_MAX_LOCATION_WITH_COLS)
-    r += ((column & ((1 << ord_map->m_column_and_range_bits) - 1))
+    r += ((column.get_value () & ((1 << ord_map->m_column_and_range_bits) - 1))
 	  << ord_map->m_range_bits);
   source_location upper_limit = LINEMAPS_MACRO_LOWEST_LOCATION (set);
   if (r >= upper_limit)
@@ -870,7 +867,7 @@ linemap_position_for_line_and_column (line_maps *set,
 source_location
 linemap_position_for_loc_and_offset (struct line_maps *set,
 				     source_location loc,
-				     unsigned int column_offset)
+				     column_num column_offset)
 {
   const line_map_ordinary * map = NULL;
 
@@ -881,7 +878,7 @@ linemap_position_for_loc_and_offset (struct line_maps *set,
   if (linemap_location_from_macro_expansion_p (set, loc))
     return loc;
 
-  if (column_offset == 0
+  if (column_offset == column_num (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.  */
@@ -893,18 +890,19 @@ linemap_position_for_loc_and_offset (struct line_maps *set,
   /* 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 + (column_offset.get_value () << map->m_range_bits))
     return loc;
 
-  linenum_type line = SOURCE_LINE (map, loc);
-  unsigned int column = SOURCE_COLUMN (map, loc);
+  line_num line = SOURCE_LINE (map, loc);
+  column_num 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)
+	 && (loc + (column_offset.get_value () << map->m_range_bits)
 	     >= MAP_START_LOCATION (&map[1])))
     {
       map = &map[1];
@@ -918,7 +916,8 @@ linemap_position_for_loc_and_offset (struct line_maps *set,
 
   /* 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)))
+  if (column
+      >= column_num (1u << (map->m_column_and_range_bits - map->m_range_bits)))
     return loc;
 
   source_location r = 
@@ -1128,7 +1127,7 @@ linemap_macro_map_loc_unwind_toward_spelling (line_maps *set,
    replacement-list of a macro expansion return the line number of the
    macro expansion point.  */
 
-int
+line_num
 linemap_get_expansion_line (struct line_maps *set,
 			    source_location location)
 {
@@ -1718,9 +1717,8 @@ linemap_expand_location (struct line_maps *set,
 			 source_location loc)
 
 {
-  expanded_location xloc;
+  expanded_location xloc = {};
 
-  memset (&xloc, 0, sizeof (xloc));
   if (IS_ADHOC_LOC (loc))
     {
       xloc.data
@@ -1798,7 +1796,7 @@ linemap_dump (FILE *stream, struct line_maps *set, unsigned ix, bool is_macro)
 		     : NULL;
 
       fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map),
-	       ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map));
+	       ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map).get_value ());
       fprintf (stream, "Included from: [%d] %s\n", includer_ix,
 	       includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None");
     }
@@ -1842,8 +1840,8 @@ linemap_dump_location (struct line_maps *set,
   else
     {
       path = LINEMAP_FILE (map);
-      l = SOURCE_LINE (map, location);
-      c = SOURCE_COLUMN (map, location);
+      l = SOURCE_LINE (map, location).get_value ();
+      c = SOURCE_COLUMN (map, location).get_value ();
       s = LINEMAP_SYSP (map) != 0;
       e = location != loc;
       if (e)
@@ -2371,7 +2369,7 @@ rich_location::maybe_add_fixit (source_location start,
 	}
 
       /* The insertion must be at the start of a line.  */
-      if (exploc_start.column != 1)
+      if (exploc_start.column != column_num (1))
 	{
 	  stop_supporting_fixits ();
 	  return;
@@ -2413,7 +2411,7 @@ fixit_hint::fixit_hint (source_location start,
 /* Does this fix-it hint affect the given line?  */
 
 bool
-fixit_hint::affects_line_p (const char *file, int line) const
+fixit_hint::affects_line_p (const char *file, line_num line) const
 {
   expanded_location exploc_start
     = linemap_client_expand_location_to_spelling_point (m_start,
diff --git a/libcpp/macro.c b/libcpp/macro.c
index c5f3ffd..57a7011 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -383,7 +383,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node,
 			 source_location loc)
 {
   const uchar *result = NULL;
-  linenum_type number = 1;
+  line_num::value_t number = 1;
 
   switch (node->value.builtin)
     {
@@ -479,7 +479,7 @@ _cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node,
       else
 	loc = linemap_resolve_location (pfile->line_table, loc,
 					LRK_MACRO_EXPANSION_POINT, NULL);
-      number = linemap_get_expansion_line (pfile->line_table, loc);
+      number = linemap_get_expansion_line (pfile->line_table, loc).get_value ();
       break;
 
       /* __STDC__ has the value 1 under normal circumstances.
-- 
1.8.5.3

