public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: David Malcolm <dmalcolm@redhat.com>
To: gcc-patches@gcc.gnu.org
Cc: David Malcolm <dmalcolm@redhat.com>
Subject: [PATCH 18/22] Track locations within string literals in tree_string
Date: Thu, 10 Sep 2015 20:31:00 -0000	[thread overview]
Message-ID: <1441916913-11547-19-git-send-email-dmalcolm@redhat.com> (raw)
In-Reply-To: <1441916913-11547-1-git-send-email-dmalcolm@redhat.com>

This patch uses the string-literal location generated in libcpp in the
previous patch, and stores it in tree_string (adding a new field there).

This hasn't been optimized.  Perhaps the case of a single unbroken run
of 1-column per-char is the most common case, so we could only bother to
store the character range info for those string literal that are exceptions
to this rule.

The patch adds unit testing via a plugin.

Screenshot:
 https://dmalcolm.fedorapeople.org/gcc/2015-09-09/string-literals.html

gcc/c-family/ChangeLog:
	* c-lex.c (ensure_string_has_location): New function.
	(lex_string): Call ensure_string_has_location on the cpp_string;
	pass in istr.loc to the call to build_string.
	(lex_charconst): Call ensure_string_has_location on the cpp_string;

gcc/cp/ChangeLog:
	* parser.c (cp_parser_string_literal): Call init_raw on the
	str.loc.  Pass in the istr.loc to the call to build_string.

gcc/testsuite/ChangeLog:
	* gcc.dg/plugin/diagnostic-test-string-literals-1.c: New file.
	* gcc.dg/plugin/diagnostic_plugin_test_string_literals.c: New file.
	* gcc.dg/plugin/plugin.exp (plugin_test_list): Add
	diagnostic_plugin_test_string_literals.c and
	diagnostic-test-string-literals-1.c.

gcc/ChangeLog:
	* tree-core.h (struct cpp_string_location): Add forward
	declaration.
	(struct tree_string): Add cpp_string_location * field "loc".
	* tree.c: Include cpplib.h.
	(build_string): Initialize TREE_STRING_LOCATION (s) to NULL.
	(cpp_string_location_stats): New global.
	(build_string): New overload.
	* tree.h (TREE_STRING_LOCATION): New macro.
	(cpp_string_location_stats): New struct and global.
	(build_string): Add overload taking an additional
	cpp_string_location * param.

libcpp/ChangeLog:
	* charset.c (cpp_string_location::get_range_between_indices): New
	method.
	* include/cpplib.h
	(cpp_string_location::get_range_between_indices): Likewise.
---
 gcc/c-family/c-lex.c                               |  23 ++-
 gcc/cp/parser.c                                    |   4 +-
 .../plugin/diagnostic-test-string-literals-1.c     | 139 +++++++++++++
 .../diagnostic_plugin_test_string_literals.c       | 215 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/plugin/plugin.exp             |   2 +
 gcc/tree-core.h                                    |   3 +
 gcc/tree.c                                         |  24 +++
 gcc/tree.h                                         |  12 ++
 libcpp/charset.c                                   |  12 ++
 libcpp/include/cpplib.h                            |   2 +
 10 files changed, 434 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic-test-string-literals-1.c
 create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.c

diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c
index f457199..6eb8fcc 100644
--- a/gcc/c-family/c-lex.c
+++ b/gcc/c-family/c-lex.c
@@ -1076,6 +1076,19 @@ interpret_fixed (const cpp_token *token, unsigned int flags)
   return value;
 }
 
+/* FIXME.  */
+
+static void
+ensure_string_has_location (const cpp_string *str, source_location src_loc)
+{
+  if (!str->loc.m_fragloc_array)
+    {
+      cpp_string *mutstr = const_cast <cpp_string *> (str);
+      cpp_string_location *strloc = &mutstr->loc;
+      strloc->init_raw (src_loc, mutstr->len, 1, line_table);
+    }
+}
+
 /* Convert a series of STRING, WSTRING, STRING16, STRING32 and/or
    UTF8STRING tokens into a tree, performing string constant
    concatenation.  TOK is the first of these.  VALP is the location to
@@ -1107,7 +1120,9 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate)
   /* Try to avoid the overhead of creating and destroying an obstack
      for the common case of just one string.  */
   cpp_string str = tok->val.str;
+  ensure_string_has_location (&str, tok->src_loc);
   cpp_string *strs = &str;
+  location_t str0_loc = tok->src_loc;
 
   /* objc_at_sign_was_seen is only used when doing Objective-C string
      concatenation.  It is 'true' if we have seen an '@' before the
@@ -1146,16 +1161,20 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate)
 	  else
 	    error ("unsupported non-standard concatenation of string literals");
 	}
+      /* FALLTHROUGH */
 
     case CPP_STRING:
       if (!concats)
 	{
 	  gcc_obstack_init (&str_ob);
+	  ensure_string_has_location (&str, str0_loc);
 	  obstack_grow (&str_ob, &str, sizeof (cpp_string));
 	}
 
       concats++;
+      ensure_string_has_location (&tok->val.str, tok->src_loc);
       obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string));
+
       if (objc_string)
 	objc_at_sign_was_seen = false;
       goto retry;
@@ -1178,7 +1197,7 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate)
        ? cpp_interpret_string : cpp_interpret_string_notranslate)
       (parse_in, strs, concats + 1, &istr, type))
     {
-      value = build_string (istr.len, (const char *) istr.text);
+      value = build_string (istr.len, (const char *) istr.text, &istr.loc);
       free (CONST_CAST (unsigned char *, istr.text));
     }
   else
@@ -1245,6 +1264,8 @@ lex_charconst (const cpp_token *token)
   unsigned int chars_seen;
   int unsignedp = 0;
 
+  ensure_string_has_location (&token->val.str, token->src_loc);
+
   result = cpp_interpret_charconst (parse_in, token,
 				    &chars_seen, &unsignedp);
 
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 17b7de0..62937ae 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -3716,6 +3716,7 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok,
 
       str.text = (const unsigned char *)TREE_STRING_POINTER (string_tree);
       str.len = TREE_STRING_LENGTH (string_tree);
+      str.loc.init_raw (tok->location, str.len, 1, line_table);
       count = 1;
 
       if (curr_tok_is_userdef_p)
@@ -3742,6 +3743,7 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok,
 	  count++;
 	  str.text = (const unsigned char *)TREE_STRING_POINTER (string_tree);
 	  str.len = TREE_STRING_LENGTH (string_tree);
+	  str.loc.init_raw (tok->location, str.len, 1, line_table);
 
 	  if (curr_tok_is_userdef_p)
 	    {
@@ -3810,7 +3812,7 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok,
   if ((translate ? cpp_interpret_string : cpp_interpret_string_notranslate)
       (parse_in, strs, count, &istr, type))
     {
-      value = build_string (istr.len, (const char *)istr.text);
+      value = build_string (istr.len, (const char *)istr.text, &istr.loc);
       free (CONST_CAST (unsigned char *, istr.text));
 
       switch (type)
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-string-literals-1.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-string-literals-1.c
new file mode 100644
index 0000000..ef3b8fe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-string-literals-1.c
@@ -0,0 +1,139 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdiagnostics-show-caret" } */
+
+/* This is a collection of unittests for ranges within string literals,
+   using diagnostic_plugin_test_string_literals, which handles
+   "__emit_string_literal_range" by generating a warning at the given
+   subset of a string literal.
+
+   The indices are 0-based.  It's easiest to verify things using string
+   literals that are runs of 0-based digits (to avoid having to count
+   characters).  */
+
+extern void __emit_string_literal_range (const char *literal,
+					 int start_idx, int end_idx);
+
+void test_simple_string_literal (void)
+{
+  __emit_string_literal_range ("0123456789", /* { dg-warning "range" } */
+			       6, 7);
+/* { dg-begin-multiline-output "" }
+   __emit_string_literal_range ("0123456789",
+                                       ^~
+   { dg-end-multiline-output "" } */
+}
+
+void test_concatenated_string_literal (void)
+{
+  __emit_string_literal_range ("01234" "56789", /* { dg-warning "range" } */
+			       3, 6);
+/* { dg-begin-multiline-output "" }
+   __emit_string_literal_range ("01234" "56789",
+                                    ^~~~~~~
+   { dg-end-multiline-output "" } */
+}
+
+void test_multiline_string_literal (void)
+{
+  __emit_string_literal_range ("01234" /* { dg-warning "range" } */
+                               "56789",
+                               3, 6);
+/* { dg-begin-multiline-output "" }
+   __emit_string_literal_range ("01234"
+                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                                "56789",
+                                ~~~  
+   { dg-end-multiline-output "" } */
+  /* FIXME: why does the above need two trailing spaces?  */
+}
+
+/* Tests of various unicode encodings.
+
+   Digits 0 through 9 are unicode code points:
+      U+0030 DIGIT ZERO
+      ...
+      U+0039 DIGIT NINE
+   However, these are not always valid as UCN (see the comment in
+   libcpp/charset.c:_cpp_valid_ucn).
+
+   Hence we need to test UCN using an alternative unicode
+   representation of numbers; let's use Roman numerals,
+   (though these start at one, not zero):
+      U+2170 SMALL ROMAN NUMERAL ONE
+      ...
+      U+2174 SMALL ROMAN NUMERAL FIVE  ("v")
+      U+2175 SMALL ROMAN NUMERAL SIX   ("vi")
+      ...
+      U+2178 SMALL ROMAN NUMERAL NINE.  */
+
+void test_hex (void)
+{
+  /* Digits 0-9, expressing digit 5 in ASCII as "\x35"
+     and with a space in place of digit 6, to terminate the escaped
+     hex code.  */
+  __emit_string_literal_range ("01234\x35 789", /* { dg-warning "range" } */
+			       3, 7);
+/* { dg-begin-multiline-output "" }
+   __emit_string_literal_range ("01234\x35 789"
+                                    ^~~~~~~~
+   { dg-end-multiline-output "" } */
+}
+
+void test_oct (void)
+{
+  /* Digits 0-9, expressing digit 5 in ASCII as "\065"
+     and with a space in place of digit 6, to terminate the escaped
+     octal code.  */
+  __emit_string_literal_range ("01234\065 789", /* { dg-warning "range" } */
+			       3, 7);
+/* { dg-begin-multiline-output "" }
+   __emit_string_literal_range ("01234\065 789"
+                                    ^~~~~~~~
+   { dg-end-multiline-output "" } */
+}
+
+void test_multiple (void)
+{
+  /* Digits 0-9, expressing digit 5 in ASCII as hex "\x35"
+     digit 6 in ASCII as octal "\066", concatenating multiple strings.  */
+  __emit_string_literal_range ("01234"  "\x35"  "\066"  "789", /* { dg-warning "range" } */
+			       3, 8);
+/* { dg-begin-multiline-output "" }
+   __emit_string_literal_range ("01234"  "\x35"  "\066"  "789",
+                                    ^~~~~~~~~~~~~~~~~~~~~~~~
+   { dg-end-multiline-output "" } */
+}
+
+void test_ucn4 (void)
+{
+  /* Digits 0-9, expressing digits 5 and 6 as Roman numerals expressed
+     as UCN 4.  */
+  __emit_string_literal_range ("01234\u2174\u2175789", /* { dg-warning "range" } */
+			       4, 7);
+/* { dg-begin-multiline-output "" }
+   __emit_string_literal_range ("01234\u2174\u2175789",
+                                     ^~~~~~~~~~~~~~
+   { dg-end-multiline-output "" } */
+}
+
+void test_ucn8 (void)
+{
+  /* Digits 0-9, expressing digits 5 and 6 as Roman numerals as UCN 8.  */
+  __emit_string_literal_range ("01234\U00002174\U00002175789", /* { dg-warning "range" } */
+			       4, 7);
+/* { dg-begin-multiline-output "" }
+   __emit_string_literal_range ("01234\U00002174\U00002175789",
+                                     ^~~~~~~~~~~~~~~~~~~~~~
+   { dg-end-multiline-output "" } */
+}
+
+void test_u8 (void)
+{
+  /* Digits 0-9.  */
+  __emit_string_literal_range (u8"0123456789", /* { dg-warning "range" } */
+			       4, 7);
+/* { dg-begin-multiline-output "" }
+   __emit_string_literal_range (u8"0123456789",
+                                       ^~~~
+   { dg-end-multiline-output "" } */
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.c
new file mode 100644
index 0000000..c6b591e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.c
@@ -0,0 +1,215 @@
+/* This plugin uses the diagnostics code to verify tracking of source code
+   locations within string literals.  */
+/* { dg-options "-O" } */
+
+#include "gcc-plugin.h"
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "toplev.h"
+#include "basic-block.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "tree.h"
+#include "tree-pass.h"
+#include "intl.h"
+#include "plugin-version.h"
+#include "diagnostic.h"
+#include "context.h"
+#include "gcc-rich-location.h"
+#include "print-tree.h"
+#include "cpplib.h"
+
+/* FIXME. hacking in a copy of this for now to get around linker issues.  */
+
+source_range
+cpp_string_location::get_range_between_indices (unsigned int start_idx,
+						unsigned int finish_idx) const
+{
+  /* This could be optimized if necessary.  */
+  source_range result;
+  result.m_start = get_loc_at_index (start_idx);
+  result.m_finish = get_range_at_index (finish_idx).m_finish;
+  return result;
+}
+
+int plugin_is_GPL_compatible;
+
+const pass_data pass_data_test_string_literals =
+{
+  GIMPLE_PASS, /* type */
+  "test_string_literals", /* name */
+  OPTGROUP_NONE, /* optinfo_flags */
+  TV_NONE, /* tv_id */
+  PROP_ssa, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  0, /* todo_flags_finish */
+};
+
+class pass_test_string_literals : public gimple_opt_pass
+{
+public:
+  pass_test_string_literals(gcc::context *ctxt)
+    : gimple_opt_pass(pass_data_test_string_literals, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  bool gate (function *) { return true; }
+  virtual unsigned int execute (function *);
+
+}; // class pass_test_string_literals
+
+/* FIXME.  */
+
+static gcall *
+check_for_named_call (gimple stmt,
+		      const char *funcname, unsigned int num_args)
+{
+  gcc_assert (funcname);
+
+  gcall *call = dyn_cast <gcall *> (stmt);
+  if (!call)
+    return NULL;
+
+  tree fndecl = gimple_call_fndecl (call);
+  if (!fndecl)
+    return NULL;
+
+  if (strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), funcname))
+    return NULL;
+
+  if (gimple_call_num_args (call) != num_args)
+    {
+      error_at (stmt->location, "expected number of args: %i (got %i)",
+		num_args, gimple_call_num_args (call));
+      return NULL;
+    }
+
+  return call;
+}
+
+static void
+emit_warning (source_range src_range)
+{
+  rich_location richloc (src_range);
+  location_range *range = richloc.get_range (0);
+  warning_at_rich_loc (&richloc, 0,
+		       "range %i:%i-%i:%i",
+		       range->m_start.line,
+		       range->m_start.column,
+		       range->m_finish.line,
+		       range->m_finish.column);
+}
+
+/* Support code for verifying that we are correctly tracking ranges
+   within string literals, for use by diagnostic-test-string-literals-*.c.  */
+
+static void
+test_string_literals (gimple stmt)
+{
+  gcall *call = check_for_named_call (stmt, "__emit_string_literal_range", 3);
+  if (!call)
+    return;
+
+#if 0
+  for (int i = 0; i < 3; i++)
+    warning_at (EXPR_LOCATION (gimple_call_arg (call, i)), 0, "arg %i", i);
+#endif
+
+  /* We expect an ADDR_EXPR with a STRING_CST inside it for the
+     initial arg.  */
+  tree t_addr_string = gimple_call_arg (call, 0);
+  if (TREE_CODE (t_addr_string) != ADDR_EXPR)
+    {
+      error_at (call->location, "string literal required for arg 1");
+      return;
+    }
+
+  tree t_string = TREE_OPERAND (t_addr_string, 0);
+  if (TREE_CODE (t_string) != STRING_CST)
+    {
+      error_at (call->location, "string literal required for arg 1");
+      return;
+    }
+
+  tree t_start_idx = gimple_call_arg (call, 1);
+  if (TREE_CODE (t_start_idx) != INTEGER_CST)
+    {
+      error_at (call->location, "integer constant required for arg 2");
+      return;
+    }
+  int start_idx = TREE_INT_CST_LOW (t_start_idx);
+
+  tree t_end_idx = gimple_call_arg (call, 2);
+  if (TREE_CODE (t_end_idx) != INTEGER_CST)
+    {
+      error_at (call->location, "integer constant required for arg 3");
+      return;
+    }
+  int end_idx = TREE_INT_CST_LOW (t_end_idx);
+
+  cpp_string_location *strloc = TREE_STRING_LOCATION (t_string);
+  gcc_assert (strloc);
+  source_range src_range
+    = strloc->get_range_between_indices (start_idx, end_idx);
+  emit_warning (src_range);
+}
+
+unsigned int
+pass_test_string_literals::execute (function *fun)
+{
+  gimple_stmt_iterator gsi;
+  basic_block bb;
+
+  FOR_EACH_BB_FN (bb, fun)
+    for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+      {
+	gimple stmt = gsi_stmt (gsi);
+	test_string_literals (stmt);
+      }
+
+  return 0;
+}
+
+static gimple_opt_pass *
+make_pass_test_string_literals (gcc::context *ctxt)
+{
+  return new pass_test_string_literals (ctxt);
+}
+
+int
+plugin_init (struct plugin_name_args *plugin_info,
+	     struct plugin_gcc_version *version)
+{
+  struct register_pass_info pass_info;
+  const char *plugin_name = plugin_info->base_name;
+  int argc = plugin_info->argc;
+  struct plugin_argument *argv = plugin_info->argv;
+
+  if (!plugin_default_version_check (version, &gcc_version))
+    return 1;
+
+  pass_info.pass = make_pass_test_string_literals (g);
+  pass_info.reference_pass_name = "ssa";
+  pass_info.ref_pass_instance_number = 1;
+  pass_info.pos_op = PASS_POS_INSERT_AFTER;
+  register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
+		     &pass_info);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index 91f6391..97d7a41 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
@@ -72,6 +72,8 @@ set plugin_test_list [list \
 	  diagnostic-test-expressions-1.c } \
     { diagnostic_plugin_show_trees.c \
 	  diagnostic-test-show-trees-1.c } \
+    { diagnostic_plugin_test_string_literals.c \
+	  diagnostic-test-string-literals-1.c } \
 ]
 
 foreach plugin_test $plugin_test_list {
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 6931ad9..7cda82f 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -1166,9 +1166,12 @@ struct GTY(()) tree_fixed_cst {
   struct fixed_value * fixed_cst_ptr;
 };
 
+struct cpp_string_location;
+
 struct GTY(()) tree_string {
   struct tree_typed typed;
   int length;
+  cpp_string_location *loc;
   char str[1];
 };
 
diff --git a/gcc/tree.c b/gcc/tree.c
index d1595c2..81d1cbd 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -75,6 +75,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "builtins.h"
 #include "print-tree.h"
 #include "ipa-utils.h"
+#include "cpplib.h"
 
 /* Tree code classes.  */
 
@@ -1931,12 +1932,35 @@ build_string (int len, const char *str)
   TREE_SET_CODE (s, STRING_CST);
   TREE_CONSTANT (s) = 1;
   TREE_STRING_LENGTH (s) = len;
+  TREE_STRING_LOCATION (s) = NULL;
   memcpy (s->string.str, str, len);
   s->string.str[len] = '\0';
 
   return s;
 }
 
+/* As above, but with per-character location information.  */
+
+struct cpp_string_location_stats cpp_string_location_stats;
+
+tree
+build_string (int len, const char *str, cpp_string_location *strloc)
+{
+  tree s = build_string (len, str);
+
+  /* Need to allocate a copy:  */
+  TREE_STRING_LOCATION (s) = ggc_alloc <cpp_string_location> ();
+  *TREE_STRING_LOCATION (s) = *strloc;
+
+  /* Maintain stats on string locations.  */
+  cpp_string_location_stats.count_all++;
+  if (strloc->trivial_p ())
+    cpp_string_location_stats.count_trivial++;
+
+  return s;
+}
+
+
 /* Return a newly constructed COMPLEX_CST node whose value is
    specified by the real and imaginary parts REAL and IMAG.
    Both REAL and IMAG should be constant nodes.  TYPE, if specified,
diff --git a/gcc/tree.h b/gcc/tree.h
index 66419d4..995937c 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -937,9 +937,20 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
 /* In a STRING_CST */
 /* In C terms, this is sizeof, not strlen.  */
 #define TREE_STRING_LENGTH(NODE) (STRING_CST_CHECK (NODE)->string.length)
+#define TREE_STRING_LOCATION(NODE) (STRING_CST_CHECK (NODE)->string.loc)
 #define TREE_STRING_POINTER(NODE) \
   ((const char *)(STRING_CST_CHECK (NODE)->string.str))
 
+extern struct cpp_string_location_stats
+{
+  /* How many have been used to construct STRING_CST.  */
+  int count_all;
+
+  /* How many of these consisted of a single run of 1-byte-per-char
+     bytes.  */
+  int count_trivial;
+} cpp_string_location_stats;
+
 /* In a COMPLEX_CST node.  */
 #define TREE_REALPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.real)
 #define TREE_IMAGPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.imag)
@@ -3791,6 +3802,7 @@ extern tree build_minus_one_cst (tree);
 extern tree build_all_ones_cst (tree);
 extern tree build_zero_cst (tree);
 extern tree build_string (int, const char *);
+extern tree build_string (int, const char *, cpp_string_location *);
 extern tree build_tree_list_stat (tree, tree MEM_STAT_DECL);
 #define build_tree_list(t, q) build_tree_list_stat (t, q MEM_STAT_INFO)
 extern tree build_tree_list_vec_stat (const vec<tree, va_gc> *MEM_STAT_DECL);
diff --git a/libcpp/charset.c b/libcpp/charset.c
index 3ae7916..f78cdf6 100644
--- a/libcpp/charset.c
+++ b/libcpp/charset.c
@@ -2028,6 +2028,18 @@ cpp_string_location::get_range_at_index (unsigned int char_idx) const
   return err;
 }
 
+/* FIXME. FINISH_IDX is within the range.  */
+source_range
+cpp_string_location::get_range_between_indices (unsigned int start_idx,
+						unsigned int finish_idx) const
+{
+  /* This could be optimized if necessary.  */
+  source_range result;
+  result.m_start = get_loc_at_index (start_idx);
+  result.m_finish = get_range_at_index (finish_idx).m_finish;
+  return result;
+}
+
 /* FIXME.  */
 bool
 cpp_string_location::trivial_p () const
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index a5e5df5..6023812 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -256,6 +256,8 @@ struct GTY(()) cpp_string_location {
 
   source_location get_loc_at_index (unsigned int idx) const;
   source_range get_range_at_index (unsigned int idx) const;
+  source_range get_range_between_indices (unsigned int start_idx,
+					  unsigned int finish_idx) const;
 
   void debug () const;
 
-- 
1.8.5.3

  parent reply	other threads:[~2015-09-10 20:31 UTC|newest]

Thread overview: 133+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-10 20:12 [PATCH 00/22] RFC: Overhaul of diagnostics David Malcolm
2015-09-10 20:12 ` [PATCH 01/22] Change of location_get_source_line signature David Malcolm
2015-09-14 19:28   ` Jeff Law
2015-09-15 17:02     ` David Malcolm
2015-09-10 20:13 ` [PATCH 08/22] C frontend: use token ranges in various diagnostics David Malcolm
2015-09-10 20:13 ` [PATCH 02/22] Testsuite: add dg-{begin|end}-multiline-output commands David Malcolm
2015-09-14 19:35   ` Jeff Law
2015-09-14 22:17     ` Bernhard Reutner-Fischer
2015-09-14 22:45       ` Jeff Law
2015-09-15 17:53         ` dejagnu version update? Mike Stump
2015-09-15 19:23           ` David Malcolm
2015-09-15 20:29             ` Jeff Law
2015-09-15 21:15               ` Bernhard Reutner-Fischer
2017-05-13 10:38                 ` Bernhard Reutner-Fischer
2017-05-13 11:06                   ` Jakub Jelinek
2017-05-13 21:12                     ` Jeff Law
2017-05-14 23:10                       ` NightStrike
2017-05-15  8:14                         ` Richard Biener
2017-05-15 19:24                           ` Mike Stump
2017-05-15 20:52                             ` Andreas Schwab
2017-05-16  9:56                     ` Jonathan Wakely
2017-05-16 12:16                       ` Bernhard Reutner-Fischer
2017-05-16 12:35                         ` Jonathan Wakely
2017-05-16 12:55                           ` Bernhard Reutner-Fischer
2017-05-16 18:41                             ` Matthias Klose
2017-05-16 19:09                           ` Mike Stump
2018-08-04 16:32                             ` Bernhard Reutner-Fischer
2018-08-06 14:33                               ` Jonathan Wakely
2018-08-06 15:26                               ` Mike Stump
2018-08-07 16:34                                 ` Segher Boessenkool
2018-08-08 11:18                                   ` Bernhard Reutner-Fischer
2018-08-08 13:35                                     ` Richard Earnshaw (lists)
2018-08-08 14:37                                     ` Michael Matz
2018-08-08 16:45                                     ` Segher Boessenkool
2021-10-27 23:00                               ` Bernhard Reutner-Fischer
2021-10-28 19:11                                 ` Jeff Law
2021-10-29  0:41                                   ` [PATCH] Bump required minimum DejaGnu version to 1.5.3 Bernhard Reutner-Fischer
2021-10-29  7:32                                     ` Richard Biener
2021-11-04 11:55                                       ` Segher Boessenkool
2021-11-04 12:22                                         ` Martin Liška
2021-11-04 19:09                                           ` Segher Boessenkool
2021-11-05  9:33                                             ` Richard Biener
2021-11-05 11:39                                               ` Jonathan Wakely
2021-11-04 12:41                                         ` Richard Biener
2021-11-04 13:50                                           ` Jonathan Wakely
2015-09-15 19:53           ` dejagnu version update? Bernhard Reutner-Fischer
2015-09-15 20:05             ` Jeff Law
2015-09-15 23:12               ` Mike Stump
2015-09-16  7:41                 ` Andreas Schwab
2015-09-16 16:19                   ` Mike Stump
2015-09-16 16:32                     ` Ramana Radhakrishnan
2015-09-16 16:39                       ` Jeff Law
2015-09-16 17:26                         ` Trevor Saunders
2015-09-16 17:46                         ` David Malcolm
2015-09-16 19:09                           ` Bernhard Reutner-Fischer
2015-09-16 19:51                             ` Mike Stump
2015-09-17  0:07                           ` Segher Boessenkool
2015-09-17 13:57                         ` Richard Earnshaw
2015-09-16 18:04                       ` Mike Stump
2015-09-16 18:58                         ` Bernhard Reutner-Fischer
2015-09-16 19:37                         ` Ramana Radhakrishnan
2015-09-16 13:17             ` Matthias Klose
2015-09-16 15:46               ` Bernhard Reutner-Fischer
2015-09-10 20:13 ` [PATCH 10/22] C++ FE: Use token ranges for various diagnostics David Malcolm
2015-09-10 20:13 ` [PATCH 06/22] PR/62314: add ability to add fixit-hints David Malcolm
2015-09-10 20:13 ` [PATCH 09/22] C frontend: store and use token ranges in c_declspecs David Malcolm
2015-09-10 20:13 ` [PATCH 20/22] Use rich locations in c-family/c-format.c David Malcolm
2015-09-10 20:13 ` [PATCH 11/22] Objective C: c/c-parser.c: use token ranges in two places David Malcolm
2015-09-10 20:13 ` [PATCH 13/22] gcc-rich-location.[ch]: add methods for working with tree ranges David Malcolm
2015-09-10 20:13 ` [PATCH 03/22] Move diagnostic_show_locus and friends out into a new source file David Malcolm
2015-09-14 19:37   ` Jeff Law
2015-09-18 18:31     ` David Malcolm
2015-09-10 20:28 ` [PATCH 07/22] Implement token range tracking within libcpp and C/C++ FEs David Malcolm
2015-09-11 14:08   ` Michael Matz
2015-09-14 19:41     ` Jeff Law
2015-09-15 10:20   ` Richard Biener
2015-09-15 10:28     ` Jakub Jelinek
2015-09-15 10:48       ` Richard Biener
2015-09-15 11:01         ` Jakub Jelinek
2015-09-16 20:29           ` David Malcolm
2015-09-17 16:54             ` David Malcolm
2015-09-17 19:15               ` Jeff Law
2015-09-17 20:06                 ` David Malcolm
2015-09-17 19:25         ` Jeff Law
2015-09-15 12:09       ` Manuel López-Ibáñez
2015-09-15 12:18         ` Richard Biener
2015-09-15 12:57           ` Manuel López-Ibáñez
2015-09-17 19:11             ` Jeff Law
2015-09-17 19:13           ` Jeff Law
2015-09-15 13:53       ` David Malcolm
2015-09-10 20:29 ` [PATCH 04/22] Reimplement diagnostic_show_locus, introducing rich_location classes David Malcolm
2015-09-11 13:44   ` Michael Matz
2015-09-11 14:12   ` Michael Matz
2015-09-11 15:15     ` David Malcolm
2015-09-10 20:29 ` [PATCH 05/22] Add overloads of inform, warning_at, etc that take a source_range David Malcolm
2015-09-10 20:30 ` [PATCH 15/22] Add plugin to recursively dump the source-ranges in a tree David Malcolm
2015-09-11  3:19   ` Martin Sebor
2015-09-10 20:30 ` [PATCH 12/22] Add source-ranges for trees David Malcolm
2015-09-10 20:30 ` [PATCH 14/22] C: capture tree ranges for various expressions David Malcolm
2015-09-10 20:31 ` [PATCH 19/22] gcc-rich-location.[ch]: add debug methods for cpp_string_location David Malcolm
2015-09-10 20:31 ` David Malcolm [this message]
2015-09-10 20:32 ` [PATCH 17/22] libcpp: add location tracking within string literals David Malcolm
2015-09-10 20:32 ` [PATCH 21/22] Use Levenshtein distance for various misspellings in C frontend David Malcolm
2015-09-10 21:11   ` Andi Kleen
2015-09-11 15:31   ` Manuel López-Ibáñez
2015-09-15 15:25     ` [PATCH WIP] Use Levenshtein distance for various misspellings in C frontend v2 David Malcolm
2015-09-15 16:25       ` Manuel López-Ibáñez
2015-09-16  8:45       ` Richard Biener
2015-09-16 13:33         ` Michael Matz
2015-09-16 14:00           ` Richard Biener
2015-09-16 15:49             ` Manuel López-Ibáñez
2015-09-17  8:46               ` Richard Biener
2015-09-17 19:32         ` Jeff Law
2015-09-17 20:05           ` David Malcolm
2015-09-17 20:52             ` Manuel López-Ibáñez
2015-10-30 12:30           ` [PATCH 0/2] Levenshtein-based suggestions (v3) David Malcolm
2015-10-30 12:30             ` [PATCH 2/2] C FE: suggest corrections for misspelled field names David Malcolm
2015-10-30 12:36             ` [PATCH 1/2] Implement Levenshtein distance David Malcolm
2015-11-02 10:56               ` Mikael Morin
2015-11-02  6:44             ` [PATCH 0/2] Levenshtein-based suggestions (v3) Jeff Law
2015-11-13  2:08               ` David Malcolm
2015-11-13  6:57                 ` Marek Polacek
2015-11-13 12:16                   ` David Malcolm
2015-11-13 15:11                     ` Marek Polacek
2015-11-13 15:44                       ` Bernd Schmidt
2015-11-13 15:53                         ` Marek Polacek
2015-11-13 15:56                           ` Jakub Jelinek
2015-11-13 16:02                             ` Marek Polacek
2015-09-10 20:32 ` [PATCH 16/22] C/C++ frontend: use tree ranges in various diagnostics David Malcolm
2015-09-10 20:50 ` [PATCH 22/22] Add fixit hints to spellchecker suggestions David Malcolm
2015-09-14 17:49 ` [PATCH 00/22] RFC: Overhaul of diagnostics Bernd Schmidt
2015-09-14 19:44   ` Jeff Law
2015-09-15  1:11     ` David Malcolm

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1441916913-11547-19-git-send-email-dmalcolm@redhat.com \
    --to=dmalcolm@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).