diff options
author | Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> | 2024-05-21 10:23:55 +0200 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2025-03-17 16:35:33 +0100 |
commit | a0f4c30e52aebcb5c71ea5eba98fb20dbbc56858 (patch) | |
tree | 2771e39bae0a9e77ae3839714809190423fed642 /gcc | |
parent | 949892cb959fa9c9d7f148aae746181cefd8b956 (diff) | |
download | gcc-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.cc | 5 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast-collector.cc | 17 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast.cc | 18 | ||||
-rw-r--r-- | gcc/rust/ast/rust-expr.h | 16 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins-include.cc | 7 | ||||
-rw-r--r-- | 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 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: |