https://gcc.gnu.org/g:81836d352866d83cd9f521d65d516b125accd2dd
commit 81836d352866d83cd9f521d65d516b125accd2dd Author: Arthur Cohen <arthur.co...@embecosm.com> Date: Wed Apr 9 18:18:30 2025 +0200 ast: Add ConstBlock and AnonConst nodes gcc/rust/ChangeLog: * ast/rust-expr.h: Declare AnonConst and ConstBlock and use them. * ast/rust-ast-full-decls.h: Likewise. * ast/rust-ast.cc: Add implementation for AnonConst and ConstBlock. * ast/rust-ast.h: Likewise. * ast/rust-ast-collector.cc (TokenCollector::visit): Likewise. * ast/rust-ast-collector.h: Likewise. * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise. * ast/rust-ast-visitor.h: Likewise. * expand/rust-derive.h: Likewise. * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise. * hir/rust-ast-lower-base.h: Likewise. * hir/rust-ast-lower-expr.cc (translate_operand_const): Likewise. * resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise. * resolve/rust-ast-resolve-base.h: Likewise. * resolve/rust-ast-resolve-expr.h: Likewise. * resolve/rust-ast-resolve-expr.cc: Likewise. Diff: --- gcc/rust/ast/rust-ast-collector.cc | 18 +++- gcc/rust/ast/rust-ast-collector.h | 2 + gcc/rust/ast/rust-ast-full-decls.h | 4 +- gcc/rust/ast/rust-ast-visitor.cc | 14 ++- gcc/rust/ast/rust-ast-visitor.h | 4 + gcc/rust/ast/rust-ast.cc | 24 +++++ gcc/rust/ast/rust-ast.h | 2 + gcc/rust/ast/rust-expr.h | 151 ++++++++++++++++++++++++++---- gcc/rust/expand/rust-derive.h | 2 + gcc/rust/hir/rust-ast-lower-base.cc | 6 ++ gcc/rust/hir/rust-ast-lower-base.h | 2 + gcc/rust/hir/rust-ast-lower-expr.cc | 8 +- gcc/rust/resolve/rust-ast-resolve-base.cc | 8 ++ gcc/rust/resolve/rust-ast-resolve-base.h | 3 + gcc/rust/resolve/rust-ast-resolve-expr.cc | 15 ++- gcc/rust/resolve/rust-ast-resolve-expr.h | 2 + 16 files changed, 237 insertions(+), 28 deletions(-) diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc index 004b4f3831dd..709908bd5445 100644 --- a/gcc/rust/ast/rust-ast-collector.cc +++ b/gcc/rust/ast/rust-ast-collector.cc @@ -1263,6 +1263,22 @@ TokenCollector::visit (BlockExpr &expr) newline (); } +void +TokenCollector::visit (AnonConst &expr) +{ + visit (expr.get_inner_expr ()); +} + +void +TokenCollector::visit (ConstBlock &expr) +{ + push (Rust::Token::make (CONST, expr.get_locus ())); + + // The inner expression is already a block expr, so we don't need to add + // curlies + visit (expr.get_const_expr ()); +} + void TokenCollector::visit (ClosureExprInnerTyped &expr) { @@ -1553,7 +1569,7 @@ TokenCollector::visit (InlineAsm &expr) break; } case RegisterType::Const: { - visit (operand.get_const ().anon_const.expr); + visit (operand.get_const ().anon_const.get_inner_expr ()); break; } case RegisterType::Sym: { diff --git a/gcc/rust/ast/rust-ast-collector.h b/gcc/rust/ast/rust-ast-collector.h index b0f1ff5fd7f1..fa835ce4c4a0 100644 --- a/gcc/rust/ast/rust-ast-collector.h +++ b/gcc/rust/ast/rust-ast-collector.h @@ -277,6 +277,8 @@ public: void visit (ClosureParam ¶m); void visit (ClosureExprInner &expr); void visit (BlockExpr &expr); + void visit (AnonConst &expr); + void visit (ConstBlock &expr); void visit (ClosureExprInnerTyped &expr); void visit (ContinueExpr &expr); void visit (BreakExpr &expr); diff --git a/gcc/rust/ast/rust-ast-full-decls.h b/gcc/rust/ast/rust-ast-full-decls.h index 418edd27cbc7..aabb1e4bd38d 100644 --- a/gcc/rust/ast/rust-ast-full-decls.h +++ b/gcc/rust/ast/rust-ast-full-decls.h @@ -115,6 +115,8 @@ struct ClosureParam; class ClosureExpr; class ClosureExprInner; class BlockExpr; +class AnonConst; +class ConstBlock; class ClosureExprInnerTyped; class ContinueExpr; class BreakExpr; @@ -145,7 +147,7 @@ struct MatchCase; class MatchExpr; class AwaitExpr; class AsyncBlockExpr; -struct AnonConst; +enum class InlineAsmOption; struct InlineAsmRegOrRegClass; class InlineAsmOperand; struct InlineAsmPlaceHolder; diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc index 8b47a81f4ed7..7caa54ba2003 100644 --- a/gcc/rust/ast/rust-ast-visitor.cc +++ b/gcc/rust/ast/rust-ast-visitor.cc @@ -455,6 +455,18 @@ DefaultASTVisitor::visit (AST::BlockExpr &expr) visit (expr.get_tail_expr ()); } +void +DefaultASTVisitor::visit (AST::ConstBlock &expr) +{ + visit (expr.get_const_expr ()); +} + +void +DefaultASTVisitor::visit (AST::AnonConst &expr) +{ + visit (expr.get_inner_expr ()); +} + void DefaultASTVisitor::visit (AST::ClosureExprInnerTyped &expr) { @@ -699,7 +711,7 @@ DefaultASTVisitor::visit (AST::InlineAsm &expr) break; } case RegisterType::Const: { - visit (operand.get_const ().anon_const.expr); + visit (operand.get_const ().anon_const.get_inner_expr ()); break; } case RegisterType::Sym: { diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h index dca8cbc645b4..2a3c7447914b 100644 --- a/gcc/rust/ast/rust-ast-visitor.h +++ b/gcc/rust/ast/rust-ast-visitor.h @@ -104,6 +104,8 @@ public: virtual void visit (FieldAccessExpr &expr) = 0; virtual void visit (ClosureExprInner &expr) = 0; virtual void visit (BlockExpr &expr) = 0; + virtual void visit (AnonConst &expr) = 0; + virtual void visit (ConstBlock &expr) = 0; virtual void visit (ClosureExprInnerTyped &expr) = 0; virtual void visit (ContinueExpr &expr) = 0; virtual void visit (BreakExpr &expr) = 0; @@ -293,6 +295,8 @@ public: virtual void visit (AST::FieldAccessExpr &expr) override; virtual void visit (AST::ClosureExprInner &expr) override; virtual void visit (AST::BlockExpr &expr) override; + virtual void visit (AST::AnonConst &expr) override; + virtual void visit (AST::ConstBlock &expr) override; virtual void visit (AST::ClosureExprInnerTyped &expr) override; virtual void visit (AST::ContinueExpr &expr) override; virtual void visit (AST::BreakExpr &expr) override; diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index 0f1a13282e08..5b797e8c49be 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -1271,6 +1271,18 @@ BlockExpr::as_string () const return str; } +std::string +AnonConst::as_string () const +{ + return "AnonConst: " + expr->as_string (); +} + +std::string +ConstBlock::as_string () const +{ + return "ConstBlock: " + expr.as_string (); +} + std::string TraitImpl::as_string () const { @@ -4512,6 +4524,18 @@ BlockExpr::accept_vis (ASTVisitor &vis) vis.visit (*this); } +void +AnonConst::accept_vis (ASTVisitor &vis) +{ + vis.visit (*this); +} + +void +ConstBlock::accept_vis (ASTVisitor &vis) +{ + vis.visit (*this); +} + void ClosureExprInnerTyped::accept_vis (ASTVisitor &vis) { diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index 34d6c093ab34..49dfcde59484 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -1256,6 +1256,8 @@ public: FieldAccess, Closure, Block, + ConstExpr, + ConstBlock, Continue, Break, Range, diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index 9ecca2251031..ba20bfaa6014 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -1214,6 +1214,8 @@ protected: class ArrayElemsCopied : public ArrayElems { std::unique_ptr<Expr> elem_to_copy; + + // TODO: This should be replaced by a ConstExpr std::unique_ptr<Expr> num_copies; location_t locus; @@ -2744,6 +2746,124 @@ protected: } }; +class AnonConst : public ExprWithBlock +{ +public: + AnonConst (std::unique_ptr<Expr> &&expr, location_t locus = UNKNOWN_LOCATION) + : ExprWithBlock (), locus (locus), expr (std::move (expr)) + { + rust_assert (this->expr); + } + + AnonConst (const AnonConst &other) + { + node_id = other.node_id; + locus = other.locus; + expr = other.expr->clone_expr (); + } + + AnonConst operator= (const AnonConst &other) + { + node_id = other.node_id; + locus = other.locus; + expr = other.expr->clone_expr (); + + return *this; + } + + std::string as_string () const override; + + Expr::Kind get_expr_kind () const override { return Expr::Kind::ConstExpr; } + + location_t get_locus () const override { return locus; } + Expr &get_inner_expr () { return *expr; } + NodeId get_node_id () const override { return node_id; } + + /* FIXME: AnonConst are always "internal" and should not have outer attributes + * - is that true? Or should we instead call + * expr->get_outer_attrs()/expr->set_outer_attrs() */ + + std::vector<Attribute> &get_outer_attrs () override + { + static auto attrs = std::vector<Attribute> (); + return attrs; + } + + void set_outer_attrs (std::vector<Attribute>) override {} + + /* FIXME: Likewise for mark_for_strip() ? */ + void mark_for_strip () override {} + bool is_marked_for_strip () const override { return false; } + + void accept_vis (ASTVisitor &vis) override; + +private: + location_t locus; + std::unique_ptr<Expr> expr; + + AnonConst *clone_expr_with_block_impl () const override + { + return new AnonConst (*this); + } +}; + +class ConstBlock : public ExprWithBlock +{ +public: + ConstBlock (AnonConst &&expr, location_t locus = UNKNOWN_LOCATION, + std::vector<Attribute> &&outer_attrs = {}) + : ExprWithBlock (), expr (std::move (expr)), + outer_attrs (std::move (outer_attrs)), locus (locus) + {} + + ConstBlock (const ConstBlock &other) + : ExprWithBlock (other), expr (other.expr), outer_attrs (other.outer_attrs), + locus (other.locus) + {} + + ConstBlock operator= (const ConstBlock &other) + { + expr = other.expr; + node_id = other.node_id; + outer_attrs = other.outer_attrs; + locus = other.locus; + + return *this; + } + + std::string as_string () const override; + + Expr::Kind get_expr_kind () const override { return Expr::Kind::ConstBlock; } + + AnonConst &get_const_expr () { return expr; } + + void accept_vis (ASTVisitor &vis) override; + + std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } + + void set_outer_attrs (std::vector<Attribute> new_attrs) override + { + outer_attrs = std::move (new_attrs); + } + + location_t get_locus () const override { return locus; } + + bool is_marked_for_strip () const override { return marked_for_strip; } + void mark_for_strip () override { marked_for_strip = true; } + +private: + AnonConst expr; + + std::vector<Attribute> outer_attrs; + location_t locus; + bool marked_for_strip = false; + + ConstBlock *clone_expr_with_block_impl () const override + { + return new ConstBlock (*this); + } +}; + // Represents a type-specified closure expression AST node class ClosureExprInnerTyped : public ClosureExpr { @@ -4822,27 +4942,18 @@ protected: } }; -struct AnonConst +// Inline-assembly specific options +enum class InlineAsmOption { - NodeId id; - std::unique_ptr<Expr> expr; - AnonConst (NodeId id, std::unique_ptr<Expr> expr) - : id (id), expr (std::move (expr)) - { - rust_assert (this->expr != nullptr); - } - AnonConst (const AnonConst &other) - { - id = other.id; - expr = other.expr->clone_expr (); - } - - AnonConst operator= (const AnonConst &other) - { - id = other.id; - expr = other.expr->clone_expr (); - return *this; - } + PURE = 1 << 0, + NOMEM = 1 << 1, + READONLY = 1 << 2, + PRESERVES_FLAGS = 1 << 3, + NORETURN = 1 << 4, + NOSTACK = 1 << 5, + ATT_SYNTAX = 1 << 6, + RAW = 1 << 7, + MAY_UNWIND = 1 << 8, }; struct InlineAsmRegOrRegClass diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h index ff7839dcafed..131b33ed7500 100644 --- a/gcc/rust/expand/rust-derive.h +++ b/gcc/rust/expand/rust-derive.h @@ -147,6 +147,8 @@ private: virtual void visit (FieldAccessExpr &expr) override final{}; virtual void visit (ClosureExprInner &expr) override final{}; virtual void visit (BlockExpr &expr) override final{}; + virtual void visit (AnonConst &expr) override final{}; + virtual void visit (ConstBlock &expr) override final{}; virtual void visit (ClosureExprInnerTyped &expr) override final{}; virtual void visit (ContinueExpr &expr) override final{}; virtual void visit (BreakExpr &expr) override final{}; diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc index 7be5922eeb4b..b3815676cc1e 100644 --- a/gcc/rust/hir/rust-ast-lower-base.cc +++ b/gcc/rust/hir/rust-ast-lower-base.cc @@ -201,6 +201,12 @@ void ASTLoweringBase::visit (AST::BlockExpr &) {} void +ASTLoweringBase::visit (AST::AnonConst &) +{} +void +ASTLoweringBase::visit (AST::ConstBlock &) +{} +void ASTLoweringBase::visit (AST::ClosureExprInnerTyped &) {} void diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h index b3017ac09c9c..653e2e88bc44 100644 --- a/gcc/rust/hir/rust-ast-lower-base.h +++ b/gcc/rust/hir/rust-ast-lower-base.h @@ -131,6 +131,8 @@ public: virtual void visit (AST::FieldAccessExpr &expr) override; virtual void visit (AST::ClosureExprInner &expr) override; virtual void visit (AST::BlockExpr &expr) override; + virtual void visit (AST::AnonConst &expr) override; + virtual void visit (AST::ConstBlock &expr) override; virtual void visit (AST::ClosureExprInnerTyped &expr) override; virtual void visit (AST::ContinueExpr &expr) override; virtual void visit (AST::BreakExpr &expr) override; diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc b/gcc/rust/hir/rust-ast-lower-expr.cc index e9e3b4e2e04d..3dee87e17b63 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.cc +++ b/gcc/rust/hir/rust-ast-lower-expr.cc @@ -867,10 +867,10 @@ HIR::InlineAsmOperand translate_operand_const (const AST::InlineAsmOperand &operand) { auto const_value = operand.get_const (); - struct HIR::AnonConst anon_const (const_value.anon_const.id, - std::unique_ptr<Expr> ( - ASTLoweringExpr::translate ( - *const_value.anon_const.expr.get ()))); + struct HIR::AnonConst anon_const ( + const_value.anon_const.get_node_id (), + std::unique_ptr<Expr> ( + ASTLoweringExpr::translate (const_value.anon_const.get_inner_expr ()))); struct HIR::InlineAsmOperand::Const cnst { anon_const diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc b/gcc/rust/resolve/rust-ast-resolve-base.cc index 397abf5b9a2c..a9efed91ed75 100644 --- a/gcc/rust/resolve/rust-ast-resolve-base.cc +++ b/gcc/rust/resolve/rust-ast-resolve-base.cc @@ -231,6 +231,14 @@ void ResolverBase::visit (AST::BlockExpr &) {} +void +ResolverBase::visit (AST::AnonConst &) +{} + +void +ResolverBase::visit (AST::ConstBlock &) +{} + void ResolverBase::visit (AST::ClosureExprInnerTyped &) {} diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h index 3a44d95bed54..70549ca35e12 100644 --- a/gcc/rust/resolve/rust-ast-resolve-base.h +++ b/gcc/rust/resolve/rust-ast-resolve-base.h @@ -21,6 +21,7 @@ #include "rust-ast-visitor.h" #include "rust-ast.h" +#include "rust-expr.h" #include "rust-name-resolver.h" #include "rust-diagnostics.h" #include "rust-location.h" @@ -85,6 +86,8 @@ public: void visit (AST::FieldAccessExpr &); void visit (AST::ClosureExprInner &); void visit (AST::BlockExpr &); + void visit (AST::AnonConst &); + void visit (AST::ConstBlock &); void visit (AST::ClosureExprInnerTyped &); void visit (AST::ContinueExpr &); void visit (AST::BreakExpr &); diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc index bc972fe74eb3..66f18bd315be 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.cc +++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc @@ -314,6 +314,18 @@ ResolveExpr::visit (AST::BlockExpr &expr) resolver->get_label_scope ().pop (); } +void +ResolveExpr::visit (AST::AnonConst &expr) +{ + ResolveExpr::go (expr.get_inner_expr (), prefix, canonical_prefix); +} + +void +ResolveExpr::visit (AST::ConstBlock &expr) +{ + ResolveExpr::go (expr.get_const_expr (), prefix, canonical_prefix); +} + void translate_operand (AST::InlineAsm &expr, const CanonicalPath &prefix, const CanonicalPath &canonical_prefix) @@ -347,7 +359,8 @@ translate_operand (AST::InlineAsm &expr, const CanonicalPath &prefix, } case RegisterType::Const: { auto anon_const = operand.get_const ().anon_const; - ResolveExpr::go (*anon_const.expr, prefix, canonical_prefix); + ResolveExpr::go (anon_const.get_inner_expr (), prefix, + canonical_prefix); break; } case RegisterType::Sym: { diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h index d43318f5d924..d45346b807d3 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.h +++ b/gcc/rust/resolve/rust-ast-resolve-expr.h @@ -56,6 +56,8 @@ public: void visit (AST::IfLetExpr &expr) override; void visit (AST::IfLetExprConseqElse &expr) override; void visit (AST::BlockExpr &expr) override; + void visit (AST::AnonConst &expr) override; + void visit (AST::ConstBlock &expr) override; void visit (AST::InlineAsm &expr) override; void visit (AST::LlvmInlineAsm &expr) override; void visit (AST::UnsafeBlockExpr &expr) override;