https://gcc.gnu.org/g:a0f4c30e52aebcb5c71ea5eba98fb20dbbc56858

commit r15-8156-ga0f4c30e52aebcb5c71ea5eba98fb20dbbc56858
Author: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>
Date:   Tue May 21 10:23:55 2024 +0200

    gccrs: Parse raw ref operator
    
    The raw ref operator is an unstable feature required to obtain a pointer
    to unaligned adresses (mainly unaligned struct fields) without UB.
    
    gcc/rust/ChangeLog:
    
            * ast/rust-ast-builder.cc (Builder::ref): Adapt constructor to the 
new
            API.
            * ast/rust-ast-collector.cc (TokenCollector::visit): Emit a raw weak
            keyword when required.
            * ast/rust-ast.cc (BorrowExpr::as_string): Change as_string
            representation to handle raw ref operator.
            * ast/rust-expr.h (class BorrowExpr): Add raw discriminant.
            * expand/rust-macro-builtins-include.cc: Adapt constructor to the 
new
            API.
            * parse/rust-parse-impl.h: Handle the raw weak keyword.
    
    Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com>

Diff:
---
 gcc/rust/ast/rust-ast-builder.cc               |  5 ++-
 gcc/rust/ast/rust-ast-collector.cc             | 17 ++++++++--
 gcc/rust/ast/rust-ast.cc                       | 18 +++++++---
 gcc/rust/ast/rust-expr.h                       | 16 +++++----
 gcc/rust/expand/rust-macro-builtins-include.cc |  7 ++--
 gcc/rust/parse/rust-parse-impl.h               | 46 ++++++++++++++++++++++----
 6 files changed, 86 insertions(+), 23 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index f4ef003adbbd..4679aa7b0f1c 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -19,6 +19,7 @@
 #include "rust-ast-builder.h"
 #include "rust-ast-full-decls.h"
 #include "rust-ast-full.h"
+#include "rust-common.h"
 #include "rust-expr.h"
 #include "rust-token.h"
 #include "rust-make-unique.h"
@@ -122,8 +123,10 @@ Builder::let (std::unique_ptr<Pattern> pattern, 
std::unique_ptr<Type> type,
 std::unique_ptr<Expr>
 Builder::ref (std::unique_ptr<Expr> &&of, bool mut) const
 {
+  auto mutability = mut ? Mutability::Mut : Mutability::Imm;
   return std::unique_ptr<Expr> (
-    new BorrowExpr (std::move (of), mut, /* is double */ false, {}, loc));
+    new BorrowExpr (std::move (of), mutability,
+                   /* raw */ false, /* is double */ false, {}, loc));
 }
 
 std::unique_ptr<Expr>
diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index d43aef80760e..bc8bc9caabef 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -843,8 +843,21 @@ TokenCollector::visit (BorrowExpr &expr)
   push (Rust::Token::make (AMP, expr.get_locus ()));
   if (expr.get_is_double_borrow ())
     push (Rust::Token::make (AMP, UNDEF_LOCATION));
-  if (expr.get_is_mut ())
-    push (Rust::Token::make (MUT, UNDEF_LOCATION));
+
+  if (expr.is_raw_borrow ())
+    {
+      push (Rust::Token::make_identifier (expr.get_locus (),
+                                         Values::WeakKeywords::RAW));
+      if (expr.get_is_mut ())
+       push (Rust::Token::make (MUT, UNDEF_LOCATION));
+      else
+       push (Rust::Token::make (CONST, UNDEF_LOCATION));
+    }
+  else
+    {
+      if (expr.get_is_mut ())
+       push (Rust::Token::make (MUT, UNDEF_LOCATION));
+    }
 
   visit (expr.get_borrowed_expr ());
 }
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 8045a6885105..38cb7cfdc64d 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "rust-ast.h"
 #include "optional.h"
 #include "rust-builtin-ast-nodes.h"
+#include "rust-common.h"
 #include "rust-system.h"
 #include "rust-ast-full.h"
 #include "rust-diagnostics.h"
@@ -1570,12 +1571,19 @@ BorrowExpr::as_string () const
 
   std::string str ("&");
 
-  if (double_borrow)
-    str += "&";
-
-  if (is_mut)
-    str += "mut ";
+  if (raw_borrow)
+    {
+      str += "raw ";
+      str += get_is_mut () ? "const " : "mut ";
+    }
+  else
+    {
+      if (double_borrow)
+       str += "&";
 
+      if (get_is_mut ())
+       str += "mut ";
+    }
   str += main_or_left_expr->as_string ();
 
   return str;
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 50c0cb146ed8..6609ad80b37e 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -2,6 +2,7 @@
 #define RUST_AST_EXPR_H
 
 #include "rust-ast.h"
+#include "rust-common.h"
 #include "rust-path.h"
 #include "rust-macro.h"
 #include "rust-operators.h"
@@ -370,18 +371,20 @@ public:
  * overloaded. */
 class BorrowExpr : public OperatorExpr
 {
-  bool is_mut;
+  Mutability mutability;
+  bool raw_borrow;
   bool double_borrow;
 
 public:
   std::string as_string () const override;
 
-  BorrowExpr (std::unique_ptr<Expr> borrow_lvalue, bool is_mut_borrow,
-             bool is_double_borrow, std::vector<Attribute> outer_attribs,
-             location_t locus)
+  BorrowExpr (std::unique_ptr<Expr> borrow_lvalue, Mutability mutability,
+             bool raw_borrow, bool is_double_borrow,
+             std::vector<Attribute> outer_attribs, location_t locus)
     : OperatorExpr (std::move (borrow_lvalue), std::move (outer_attribs),
                    locus),
-      is_mut (is_mut_borrow), double_borrow (is_double_borrow)
+      mutability (mutability), raw_borrow (raw_borrow),
+      double_borrow (is_double_borrow)
   {}
 
   void accept_vis (ASTVisitor &vis) override;
@@ -393,9 +396,10 @@ public:
     return *main_or_left_expr;
   }
 
-  bool get_is_mut () const { return is_mut; }
+  bool get_is_mut () const { return mutability == Mutability::Mut; }
 
   bool get_is_double_borrow () const { return double_borrow; }
+  bool is_raw_borrow () const { return raw_borrow; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
diff --git a/gcc/rust/expand/rust-macro-builtins-include.cc 
b/gcc/rust/expand/rust-macro-builtins-include.cc
index acfbfbb2fc94..49596a84900b 100644
--- a/gcc/rust/expand/rust-macro-builtins-include.cc
+++ b/gcc/rust/expand/rust-macro-builtins-include.cc
@@ -16,6 +16,7 @@
 // along with GCC; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
+#include "rust-common.h"
 #include "rust-macro-builtins.h"
 #include "rust-macro-builtins-helpers.h"
 #include "optional.h"
@@ -77,7 +78,9 @@ MacroBuiltin::include_bytes_handler (location_t invoc_locus,
     new AST::ArrayExpr (std::move (elems), {}, {}, invoc_locus));
 
   auto borrow = std::unique_ptr<AST::Expr> (
-    new AST::BorrowExpr (std::move (array), false, false, {}, invoc_locus));
+    new AST::BorrowExpr (std::move (array), Mutability::Imm,
+                        /* raw borrow */ false,
+                        /* double borrow */ false, {}, invoc_locus));
 
   auto node = AST::SingleASTNode (std::move (borrow));
 
@@ -246,4 +249,4 @@ MacroBuiltin::include_handler (location_t invoc_locus,
   // string literal.
   return AST::Fragment (nodes, std::vector<std::unique_ptr<AST::Token>> ());
 }
-} // namespace Rust
\ No newline at end of file
+} // namespace Rust
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index e2a9b199a9ba..91f09f64fe3b 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -12376,33 +12376,64 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
       case AMP: {
        // (single) "borrow" expression - shared (mutable) or immutable
        std::unique_ptr<AST::Expr> expr = nullptr;
-       bool is_mut_borrow = false;
+       Mutability mutability = Mutability::Imm;
+       bool raw_borrow = false;
 
        ParseRestrictions entered_from_unary;
        entered_from_unary.entered_from_unary = true;
        if (!restrictions.can_be_struct_expr)
          entered_from_unary.can_be_struct_expr = false;
 
-       if (lexer.peek_token ()->get_id () == MUT)
+       auto is_mutability = [] (const_TokenPtr token) {
+         return token->get_id () == CONST || token->get_id () == MUT;
+       };
+
+       auto t = lexer.peek_token ();
+       // Weak raw keyword, we look (1) ahead and treat it as an identifier if
+       // there is no mut nor const.
+       if (t->get_id () == IDENTIFIER
+           && t->get_str () == Values::WeakKeywords::RAW
+           && is_mutability (lexer.peek_token (1)))
+         {
+           lexer.skip_token ();
+           switch (lexer.peek_token ()->get_id ())
+             {
+             case MUT:
+               mutability = Mutability::Mut;
+               break;
+             case CONST:
+               mutability = Mutability::Imm;
+               break;
+             default:
+               rust_error_at (lexer.peek_token ()->get_locus (),
+                              "raw borrow should be either const or mut");
+             }
+           lexer.skip_token ();
+           expr = parse_expr (LBP_UNARY_AMP_MUT, {}, entered_from_unary);
+           raw_borrow = true;
+         }
+       else if (t->get_id () == MUT)
          {
            lexer.skip_token ();
            expr = parse_expr (LBP_UNARY_AMP_MUT, {}, entered_from_unary);
-           is_mut_borrow = true;
+           mutability = Mutability::Mut;
+           raw_borrow = false;
          }
        else
          {
            expr = parse_expr (LBP_UNARY_AMP, {}, entered_from_unary);
+           raw_borrow = false;
          }
 
        // FIXME: allow outer attributes on expression
        return std::unique_ptr<AST::BorrowExpr> (
-         new AST::BorrowExpr (std::move (expr), is_mut_borrow, false,
+         new AST::BorrowExpr (std::move (expr), mutability, raw_borrow, false,
                               std::move (outer_attrs), tok->get_locus ()));
       }
       case LOGICAL_AND: {
        // (double) "borrow" expression - shared (mutable) or immutable
        std::unique_ptr<AST::Expr> expr = nullptr;
-       bool is_mut_borrow = false;
+       Mutability mutability = Mutability::Imm;
 
        ParseRestrictions entered_from_unary;
        entered_from_unary.entered_from_unary = true;
@@ -12411,16 +12442,17 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
          {
            lexer.skip_token ();
            expr = parse_expr (LBP_UNARY_AMP_MUT, {}, entered_from_unary);
-           is_mut_borrow = true;
+           mutability = Mutability::Mut;
          }
        else
          {
            expr = parse_expr (LBP_UNARY_AMP, {}, entered_from_unary);
+           mutability = Mutability::Imm;
          }
 
        // FIXME: allow outer attributes on expression
        return std::unique_ptr<AST::BorrowExpr> (
-         new AST::BorrowExpr (std::move (expr), is_mut_borrow, true,
+         new AST::BorrowExpr (std::move (expr), mutability, false, true,
                               std::move (outer_attrs), tok->get_locus ()));
       }
     case OR:

Reply via email to