aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>2024-05-21 10:23:55 +0200
committerArthur Cohen <arthur.cohen@embecosm.com>2025-03-17 16:35:33 +0100
commita0f4c30e52aebcb5c71ea5eba98fb20dbbc56858 (patch)
tree2771e39bae0a9e77ae3839714809190423fed642 /gcc
parent949892cb959fa9c9d7f148aae746181cefd8b956 (diff)
downloadgcc-a0f4c30e52aebcb5c71ea5eba98fb20dbbc56858.zip
gcc-a0f4c30e52aebcb5c71ea5eba98fb20dbbc56858.tar.gz
gcc-a0f4c30e52aebcb5c71ea5eba98fb20dbbc56858.tar.bz2
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.patry@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-ast-builder.cc5
-rw-r--r--gcc/rust/ast/rust-ast-collector.cc17
-rw-r--r--gcc/rust/ast/rust-ast.cc18
-rw-r--r--gcc/rust/ast/rust-expr.h16
-rw-r--r--gcc/rust/expand/rust-macro-builtins-include.cc7
-rw-r--r--gcc/rust/parse/rust-parse-impl.h46
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 f4ef003..4679aa7 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 d43aef8..bc8bc9c 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 8045a68..38cb7cf 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 50c0cb1..6609ad8 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 acfbfbb..49596a84 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 e2a9b19..91f09f6 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: