From 91049bc4a17837a4c677c95f27a2d172c0a70390 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 7 Jul 2016 10:44:04 -0400
Subject: [PATCH 19/25] FIXME: WIP on unification

---
 gcc/input.c             |  6 +++++-
 libcpp/charset.c        | 51 +++++++++++++++++++++++++++++--------------------
 libcpp/include/cpplib.h | 18 ++++++++++++++++-
 libcpp/internal.h       | 15 ---------------
 4 files changed, 52 insertions(+), 38 deletions(-)

diff --git a/gcc/input.c b/gcc/input.c
index 10d0a90..6c2f73c 100644
--- a/gcc/input.c
+++ b/gcc/input.c
@@ -1219,6 +1219,7 @@ get_substring_ranges_for_loc (cpp_reader *pfile,
     concats->get_string_concatenation (strloc, &num_locs, &strlocs);
 
   auto_vec <cpp_string> strs (num_locs);
+  auto_vec <cpp_string_location_reader> loc_readers (num_locs);
   for (int i = 0; i < num_locs; i++)
     {
       /* Get range of strloc.  We will use it to locate the start and finish
@@ -1262,6 +1263,8 @@ get_substring_ranges_for_loc (cpp_reader *pfile,
       from.len = literal_length;
       from.text = (const unsigned char *)literal;
       strs.safe_push (from);
+      cpp_string_location_reader loc_reader (strlocs[i], line_table);
+      loc_readers.safe_push (loc_reader);
     }
 
   /* Rerun cpp_interpret_string, or rather, a modified version of it.  */
@@ -1271,7 +1274,8 @@ get_substring_ranges_for_loc (cpp_reader *pfile,
      For now, we simply constrain ourselves to the UTF-8 case (for both
      source and execution encoding).  */
 
-  if (!cpp_interpret_string_ranges (pfile, strs.address (), strlocs, num_locs,
+  if (!cpp_interpret_string_ranges (pfile, strs.address (),
+				    loc_readers.address (), num_locs,
 				    &ranges))
     return false;
 
diff --git a/libcpp/charset.c b/libcpp/charset.c
index f26c275..205025f 100644
--- a/libcpp/charset.c
+++ b/libcpp/charset.c
@@ -1593,11 +1593,11 @@ converter_for_type (cpp_reader *pfile, enum cpp_ttype type)
    concatenated.  WIDE indicates whether or not to produce a wide
    string.  The result is written into TO.  Returns true for success,
    false for failure.  */
-#if 0
+#if 1
 bool
 cpp_interpret_string_unified (cpp_reader *pfile, const cpp_string *from, size_t count,
 			      cpp_string *to,  enum cpp_ttype type,
-			      source_location *from_locations,
+			      cpp_string_location_reader *loc_readers,
 			      cpp_substring_ranges *out)
 {
   struct _cpp_strbuf tbuf;
@@ -1614,18 +1614,21 @@ cpp_interpret_string_unified (cpp_reader *pfile, const cpp_string *from, size_t
 
   for (i = 0; i < count; i++)
     {
-      // FIXME: how to conditionalize this?
-      if (out)
-	cpp_string_location_reader loc_reader (from_locations[i], pfile->line_table);
+      cpp_string_location_reader *loc_reader = NULL;
+      if (loc_readers)
+	loc_reader = &loc_readers[i];
+
       p = from[i].text;
       if (*p == 'u')
 	{
 	  p++;
-	  loc_reader.get_next ();
+	  if (loc_reader)
+	    loc_reader->get_next ();
 	  if (*p == '8')
 	    {
 	      p++;
-	      loc_reader.get_next ();
+	      if (loc_reader)
+		loc_reader->get_next ();
 	    }
 	}
       else if (*p == 'L' || *p == 'U') p++;
@@ -1643,11 +1646,11 @@ cpp_interpret_string_unified (cpp_reader *pfile, const cpp_string *from, size_t
 	  if (limit >= p + (p - prefix) + 1)
 	    limit -= (p - prefix) + 1;
 
-	  if (out)
+	  if (loc_reader)
 	    /* Raw strings are all normal characters; assume UTF-8 to UTF-8
 	       conversion, hence these can be all treated as one byte in the
 	       result per column.  */
-	    out->add_n_ranges (limit - p, loc_reader);
+	    out->add_n_ranges (limit - p, *loc_reader);
 	  else
 	    /* Raw strings are all normal characters; these can be fed
 	       directly to convert_cset.  */
@@ -1659,7 +1662,8 @@ cpp_interpret_string_unified (cpp_reader *pfile, const cpp_string *from, size_t
 
       /* Skip leading quote.  */
       p++;
-      loc_reader.get_next ();
+      if (loc_reader)
+	loc_reader->get_next ();
 
       limit = from[i].text + from[i].len - 1; /* Skip trailing quote.  */
 
@@ -1672,8 +1676,8 @@ cpp_interpret_string_unified (cpp_reader *pfile, const cpp_string *from, size_t
 	    {
 	      /* We have a run of normal characters; these can be fed
 		 directly to convert_cset.  */
-	      if (out)
-		out->add_n_ranges (p - base, loc_reader);
+	      if (loc_reader)
+		out->add_n_ranges (p - base, *loc_reader);
 	      else
 		if (!APPLY_CONVERSION (cvt, base, p - base, &tbuf))//, &loc_reader,
 		  //false))
@@ -1684,7 +1688,7 @@ cpp_interpret_string_unified (cpp_reader *pfile, const cpp_string *from, size_t
 
 	  // FIXME: do we need to conditionalize the &tbuf on "to"?
 	  p = convert_escape_unified (pfile, p + 1, limit, &tbuf, cvt,
-				      &loc_reader, *out);
+				      loc_reader, out);
 	}
     }
 
@@ -1809,7 +1813,7 @@ cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count,
 
 bool
 cpp_interpret_string_ranges (cpp_reader *pfile, const cpp_string *from,
-			     source_location *from_locations,
+			     cpp_string_location_reader *loc_readers,
 			     size_t count,
 			     cpp_substring_ranges *out)
 {
@@ -1822,16 +1826,18 @@ cpp_interpret_string_ranges (cpp_reader *pfile, const cpp_string *from,
 
   for (i = 0; i < count; i++)
     {
-      cpp_string_location_reader loc_reader (from_locations[i], pfile->line_table);
+      cpp_string_location_reader *loc_reader = &loc_readers[i];
       p = from[i].text;
       if (*p == 'u')
 	{
 	  p++;
-	  loc_reader.get_next ();
+	  if (loc_reader)
+	    loc_reader->get_next ();
 	  if (*p == '8')
 	    {
 	      p++;
-	      loc_reader.get_next ();
+	      if (loc_reader)
+		loc_reader->get_next ();
 	    }
 	}
       else if (*p == 'L' || *p == 'U') p++;
@@ -1852,14 +1858,16 @@ cpp_interpret_string_ranges (cpp_reader *pfile, const cpp_string *from,
 	  /* Raw strings are all normal characters; assume UTF-8 to UTF-8
 	     conversion, hence these can be all treated as one byte in the result
 	     per column.  */
-	  out->add_n_ranges (limit - p, loc_reader);
+	  if (loc_reader)
+	    out->add_n_ranges (limit - p, *loc_reader);
 
 	  continue;
 	}
 
       /* Skip leading quote.  */
       p++;
-      loc_reader.get_next ();
+      if (loc_reader)
+	loc_reader->get_next ();
 
       limit = from[i].text + from[i].len - 1; /* Skip trailing quote.  */
 
@@ -1872,12 +1880,13 @@ cpp_interpret_string_ranges (cpp_reader *pfile, const cpp_string *from,
 	    {
 	      /* We have a run of normal characters; these can be fed
 		 directly to convert_cset.  */
-	      out->add_n_ranges (p - base, loc_reader);
+	      if (loc_reader)
+		out->add_n_ranges (p - base, *loc_reader);
 	    }
 	  if (p == limit)
 	    break;
 
-	  p = convert_escape_ranges (pfile, p + 1, limit, &loc_reader, *out);
+	  p = convert_escape_ranges (pfile, p + 1, limit, loc_reader, *out);
 	}
     }
   return true;
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 27f5bbf..2b06d2d 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -859,7 +859,7 @@ extern bool cpp_interpret_string (cpp_reader *,
 				  cpp_string *, enum cpp_ttype);
 extern bool cpp_interpret_string_ranges (cpp_reader *pfile,
 					 const cpp_string *from,
-					 source_location *from_locations,
+					 cpp_string_location_reader *loc_readers, // FIXME: overlong line
 					 size_t count,
 					 cpp_substring_ranges *out);
 extern bool cpp_interpret_string_notranslate (cpp_reader *,
@@ -1153,4 +1153,20 @@ extern bool cpp_userdef_char_p
 extern const char * cpp_get_userdef_suffix
   (const cpp_token *);
 
+/* A class for iterating through the source locations within a
+   string.  */
+
+class cpp_string_location_reader {
+ public:
+  cpp_string_location_reader (source_location src_loc,
+			      line_maps *line_table);
+
+  source_range get_next ();
+
+ private:
+  source_location m_loc;
+  int m_offset_per_column;
+  line_maps *m_line_table;
+};
+
 #endif /* ! LIBCPP_CPPLIB_H */
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 06cec86..d669415 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -895,21 +895,6 @@ int linemap_get_expansion_line (struct line_maps *,
 const char* linemap_get_expansion_filename (struct line_maps *,
 					    source_location);
 
-/* A class for iterating through the source-locations within a
-   string.  */
-class cpp_string_location_reader {
- public:
-  cpp_string_location_reader (source_location src_loc,
-			      line_maps *line_table);
-
-  source_range get_next ();
-
- private:
-  source_location m_loc;
-  int m_offset_per_column;
-  line_maps *m_line_table;
-};
-
 #ifdef __cplusplus
 }
 #endif
-- 
1.8.5.3

