rust: Support raw identifiers

Message ID 20200704030430.822085-1-dxu@dxuuu.xyz
State New
Headers show
Series
  • rust: Support raw identifiers
Related show

Commit Message

Daniel Xu July 4, 2020, 3:04 a.m.
This patch adds rust raw identifier support. Raw identifiers are
detailed here: https://doc.rust-lang.org/reference/identifiers.html .

        PR 23427
gdb/
        * rust-exp.y: Lex raw identifiers
gdb/testsuite/
        * gdb.rust/expr.exp: Fix test
        * gdb.rust/raw_ident.exp: Add test file
        * gdb.rust/raw_ident.rs: Add test file

Signed-off-by: Daniel Xu <dxu@dxuuu.xyz>

---
 gdb/rust-exp.y                       | 15 +++++++++++-
 gdb/testsuite/gdb.rust/expr.exp      |  2 +-
 gdb/testsuite/gdb.rust/raw_ident.exp | 34 ++++++++++++++++++++++++++++
 gdb/testsuite/gdb.rust/raw_ident.rs  | 23 +++++++++++++++++++
 4 files changed, 72 insertions(+), 2 deletions(-)
 create mode 100644 gdb/testsuite/gdb.rust/raw_ident.exp
 create mode 100644 gdb/testsuite/gdb.rust/raw_ident.rs

-- 
2.27.0

Comments

Tom Tromey July 11, 2020, 10:05 p.m. | #1
>>>>> "Daniel" == Daniel Xu <dxu@dxuuu.xyz> writes:


Daniel> This patch adds rust raw identifier support. Raw identifiers are
Daniel> detailed here: https://doc.rust-lang.org/reference/identifiers.html .

Daniel>         PR 23427

This should be mentioned in both ChangeLog files, and should read
"PR rust/23427" -- the parser is a bit picky.

Daniel> @@ -1402,6 +1402,8 @@ rust_parser::lex_identifier (YYSTYPE *lvalp)
Daniel>    while ((pstate->lexptr[0] >= 'a' && pstate->lexptr[0] <= 'z')
Daniel>  	 || (pstate->lexptr[0] >= 'A' && pstate->lexptr[0] <= 'Z')
Daniel>  	 || pstate->lexptr[0] == '_'
Daniel> +	 || (pstate->lexptr[0] == '#' && pstate->lexptr - start == 1
Daniel> +             && *start == 'r')

This seems maybe a little roundabout, but OTOH the convenience variable
code isn't any better.

This patch is ok.  I think given the size we will need copyright
paperwork before we can check it in.  Do you have that?  If not, contact
me off-list and I will get you started.

thanks,
Tom

Patch

diff --git a/gdb/rust-exp.y b/gdb/rust-exp.y
index 4e7878f67e..c745610df6 100644
--- a/gdb/rust-exp.y
+++ b/gdb/rust-exp.y
@@ -1402,6 +1402,8 @@  rust_parser::lex_identifier (YYSTYPE *lvalp)
   while ((pstate->lexptr[0] >= 'a' && pstate->lexptr[0] <= 'z')
 	 || (pstate->lexptr[0] >= 'A' && pstate->lexptr[0] <= 'Z')
 	 || pstate->lexptr[0] == '_'
+	 || (pstate->lexptr[0] == '#' && pstate->lexptr - start == 1
+             && *start == 'r')
 	 || (is_gdb_var && pstate->lexptr[0] == '$')
 	 || (pstate->lexptr[0] >= '0' && pstate->lexptr[0] <= '9'))
     ++pstate->lexptr;
@@ -1438,9 +1440,17 @@  rust_parser::lex_identifier (YYSTYPE *lvalp)
       pstate->lexptr = start;
       return 0;
     }
+  else if (token == NULL && length == 2 && strncmp (start, "r#", length) == 0)
+    error (_("Invalid raw identifier"));
 
   if (token == NULL || (pstate->parse_completion && pstate->lexptr[0] == '\0'))
-    lvalp->sval = make_stoken (copy_name (start, length));
+    {
+      /* Handle raw identifiers */
+      if (length > 1 && start[0] == 'r' && start[1] == '#')
+        start += 2;
+
+      lvalp->sval = make_stoken (copy_name (start, length));
+    }
 
   if (pstate->parse_completion && pstate->lexptr[0] == '\0')
     {
@@ -2773,6 +2783,8 @@  rust_lex_tests (void)
   rust_lex_exception_test (&parser, "'\\u{}", "Not enough hex digits seen");
   rust_lex_exception_test (&parser, "'\\Q'", "Invalid escape \\Q in literal");
   rust_lex_exception_test (&parser, "b'\\Q'", "Invalid escape \\Q in literal");
+  rust_lex_exception_test (&parser, "r##if", "Invalid raw identifier");
+  rust_lex_exception_test (&parser, "r#", "Invalid raw identifier");
 
   rust_lex_int_test (&parser, "23", 23, DECIMAL_INTEGER);
   rust_lex_int_test (&parser, "2_344__29", 234429, INTEGER);
@@ -2797,6 +2809,7 @@  rust_lex_tests (void)
   rust_lex_stringish_test (&parser, "hibob", "hibob", IDENT);
   rust_lex_stringish_test (&parser, "hibob__93", "hibob__93", IDENT);
   rust_lex_stringish_test (&parser, "thread", "thread", IDENT);
+  rust_lex_stringish_test (&parser, "r#if", "if", IDENT);
 
   rust_lex_stringish_test (&parser, "\"string\"", "string", STRING);
   rust_lex_stringish_test (&parser, "\"str\\ting\"", "str\ting", STRING);
diff --git a/gdb/testsuite/gdb.rust/expr.exp b/gdb/testsuite/gdb.rust/expr.exp
index 29a628ea78..6e700896d9 100644
--- a/gdb/testsuite/gdb.rust/expr.exp
+++ b/gdb/testsuite/gdb.rust/expr.exp
@@ -136,6 +136,6 @@  gdb_test "print \[mut 23usize; 4\]" " = \\\[23, 23, 23, 23\\\]"
 # Test lexer corner cases.
 gdb_test "print 0x0 as *mut ()" " = \\\(\\*mut \\\(\\\)\\\) 0x0"
 gdb_test "print 0x0 as fn(i64) -> ()" " = \\\(\\*mut fn \\\(i64\\\) -> \\\(\\\)\\\) 0x0"
-gdb_test "print r#" "syntax error in expression, near `#'\\."
+gdb_test "print r#" "Invalid raw identifier"
 
 gdb_test "printf \"%d %d\\n\", 23+1, 23-1" "24 22"
diff --git a/gdb/testsuite/gdb.rust/raw_ident.exp b/gdb/testsuite/gdb.rust/raw_ident.exp
new file mode 100644
index 0000000000..0a8f7c0c5e
--- /dev/null
+++ b/gdb/testsuite/gdb.rust/raw_ident.exp
@@ -0,0 +1,34 @@ 
+# Copyright (C) 2017-2020 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Test raw identifier support
+
+load_lib rust-support.exp
+if {[skip_rust_tests]} {
+    continue
+}
+
+standard_testfile .rs
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug rust}]} {
+    return -1
+}
+
+set line [gdb_get_line_number "set breakpoint here"]
+if {![runto ${srcfile}:$line]} {
+    untested "could not run to breakpoint"
+    return -1
+}
+
+gdb_test "print r#if" "5"
diff --git a/gdb/testsuite/gdb.rust/raw_ident.rs b/gdb/testsuite/gdb.rust/raw_ident.rs
new file mode 100644
index 0000000000..95ec99fb13
--- /dev/null
+++ b/gdb/testsuite/gdb.rust/raw_ident.rs
@@ -0,0 +1,23 @@ 
+// Copyright (C) 2017-2020 Free Software Foundation, Inc.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![allow(unused_assignments)]
+
+fn main() {
+    let r#if = 5;
+    let z = r#if;                  // set breakpoint here
+}