diff options
Diffstat (limited to 'gcc/rust/ast/rust-expr.h')
-rw-r--r-- | gcc/rust/ast/rust-expr.h | 500 |
1 files changed, 402 insertions, 98 deletions
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index 9477bf0..fdb6360 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -15,7 +15,7 @@ namespace AST { // Loop label expression AST node used with break and continue expressions // TODO: inline? -class LoopLabel /*: public Node*/ +class LoopLabel /*: public Visitable*/ { Lifetime label; // or type LIFETIME_OR_LABEL location_t locus; @@ -31,11 +31,6 @@ public: {} // Returns whether the LoopLabel is in an error state. - bool is_error () const { return label.is_error (); } - - // Creates an error state LoopLabel. - static LoopLabel error () { return LoopLabel (Lifetime::error ()); } - location_t get_locus () const { return locus; } Lifetime &get_lifetime () { return label; } @@ -117,6 +112,8 @@ public: outer_attrs = std::move (new_attrs); } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Literal; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -365,6 +362,8 @@ public: { outer_attrs = std::move (new_attrs); } + + Expr::Kind get_expr_kind () const override { return Expr::Kind::Operator; } }; /* Unary prefix & or &mut (or && and &&mut) borrow operator. Cannot be @@ -403,6 +402,8 @@ public: bool get_is_double_borrow () const { return double_borrow; } bool is_raw_borrow () const { return raw_borrow; } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Borrow; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -433,6 +434,8 @@ public: return *main_or_left_expr; } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Dereference; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -464,6 +467,11 @@ public: return *main_or_left_expr; } + Expr::Kind get_expr_kind () const override + { + return Expr::Kind::ErrorPropagation; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -507,6 +515,8 @@ public: return *main_or_left_expr; } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Negation; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -595,6 +605,11 @@ public: void visit_lhs (ASTVisitor &vis) { main_or_left_expr->accept_vis (vis); } void visit_rhs (ASTVisitor &vis) { right_expr->accept_vis (vis); } + Expr::Kind get_expr_kind () const override + { + return Expr::Kind::ArithmeticOrLogical; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -682,6 +697,8 @@ public: ExprType get_kind () { return expr_type; } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Comparison; } + /* TODO: implement via a function call to std::cmp::PartialEq::eq(&op1, &op2) * maybe? */ protected: @@ -770,6 +787,8 @@ public: ExprType get_kind () { return expr_type; } + Expr::Kind get_expr_kind () const override { return Expr::Kind::LazyBoolean; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -832,6 +851,8 @@ public: return *type_to_convert_to; } + Expr::Kind get_expr_kind () const override { return Expr::Kind::TypeCast; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -910,6 +931,8 @@ public: return *right_expr; } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Assignment; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -996,6 +1019,11 @@ public: return right_expr; } + Expr::Kind get_expr_kind () const override + { + return Expr::Kind::CompoundAssignment; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -1090,6 +1118,8 @@ public: return expr_in_parens; } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Grouped; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -1319,6 +1349,8 @@ public: return internal_elements; } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Array; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -1424,6 +1456,8 @@ public: outer_attrs = std::move (new_attrs); } + Expr::Kind get_expr_kind () const override { return Expr::Kind::ArrayIndex; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -1520,6 +1554,8 @@ public: bool is_unit () const { return tuple_elems.size () == 0; } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Tuple; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -1607,6 +1643,8 @@ public: outer_attrs = std::move (new_attrs); } + Expr::Kind get_expr_kind () const override { return Expr::Kind::TupleIndex; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -1650,6 +1688,8 @@ public: { outer_attrs = std::move (new_attrs); } + + Expr::Kind get_expr_kind () const override { return Expr::Kind::Struct; } }; // Actual AST node of the struct creator (with no fields). Not abstract! @@ -2123,6 +2163,8 @@ public: return *function; } + std::unique_ptr<Expr> &get_function_expr_ptr () { return function; } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } @@ -2131,6 +2173,8 @@ public: outer_attrs = std::move (new_attrs); } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Call; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -2234,6 +2278,8 @@ public: outer_attrs = std::move (new_attrs); } + Expr::Kind get_expr_kind () const override { return Expr::Kind::MethodCall; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -2319,6 +2365,8 @@ public: outer_attrs = std::move (new_attrs); } + Expr::Kind get_expr_kind () const override { return Expr::Kind::FieldAccess; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -2454,6 +2502,8 @@ public: } bool get_has_move () const { return has_move; } + + Expr::Kind get_expr_kind () const override { return Expr::Kind::Closure; } }; // Represents a non-type-specified closure expression AST node @@ -2535,7 +2585,7 @@ class BlockExpr : public ExprWithBlock std::vector<Attribute> inner_attrs; std::vector<std::unique_ptr<Stmt> > statements; std::unique_ptr<Expr> expr; - LoopLabel label; + tl::optional<LoopLabel> label; location_t start_locus; location_t end_locus; bool marked_for_strip = false; @@ -2552,8 +2602,9 @@ public: BlockExpr (std::vector<std::unique_ptr<Stmt> > block_statements, std::unique_ptr<Expr> block_expr, std::vector<Attribute> inner_attribs, - std::vector<Attribute> outer_attribs, LoopLabel label, - location_t start_locus, location_t end_locus) + std::vector<Attribute> outer_attribs, + tl::optional<LoopLabel> label, location_t start_locus, + location_t end_locus) : outer_attrs (std::move (outer_attribs)), inner_attrs (std::move (inner_attribs)), statements (std::move (block_statements)), expr (std::move (block_expr)), @@ -2672,8 +2723,10 @@ public: outer_attrs = std::move (new_attrs); } - bool has_label () { return !label.is_error (); } - LoopLabel &get_label () { return label; } + bool has_label () { return label.has_value (); } + LoopLabel &get_label () { return label.value (); } + + Expr::Kind get_expr_kind () const override { return Expr::Kind::Block; } protected: /* Use covariance to implement clone function as returning this object rather @@ -2791,7 +2844,7 @@ protected: class ContinueExpr : public ExprWithoutBlock { std::vector<Attribute> outer_attrs; - Lifetime label; + tl::optional<Lifetime> label; location_t locus; // TODO: find another way to store this to save memory? @@ -2801,11 +2854,11 @@ public: std::string as_string () const override; // Returns true if the continue expr has a label. - bool has_label () const { return !label.is_error (); } + bool has_label () const { return label.has_value (); } // Constructor for a ContinueExpr with a label. - ContinueExpr (Lifetime label, std::vector<Attribute> outer_attribs, - location_t locus) + ContinueExpr (tl::optional<Lifetime> label, + std::vector<Attribute> outer_attribs, location_t locus) : outer_attrs (std::move (outer_attribs)), label (std::move (label)), locus (locus) {} @@ -2826,7 +2879,13 @@ public: outer_attrs = std::move (new_attrs); } - Lifetime &get_label () { return label; } + Lifetime &get_label_unchecked () { return label.value (); } + const Lifetime &get_label_unchecked () const { return label.value (); } + + tl::optional<Lifetime> &get_label () { return label; } + const tl::optional<Lifetime> &get_label () const { return label; } + + Expr::Kind get_expr_kind () const override { return Expr::Kind::Continue; } protected: /* Use covariance to implement clone function as returning this object rather @@ -2842,7 +2901,7 @@ protected: class BreakExpr : public ExprWithoutBlock { std::vector<Attribute> outer_attrs; - LoopLabel label; + tl::optional<LoopLabel> label; std::unique_ptr<Expr> break_expr; location_t locus; @@ -2853,14 +2912,15 @@ public: std::string as_string () const override; // Returns whether the break expression has a label or not. - bool has_label () const { return !label.is_error (); } + bool has_label () const { return label.has_value (); } /* Returns whether the break expression has an expression used in the break or * not. */ bool has_break_expr () const { return break_expr != nullptr; } // Constructor for a break expression - BreakExpr (LoopLabel break_label, std::unique_ptr<Expr> expr_in_break, + BreakExpr (tl::optional<LoopLabel> break_label, + std::unique_ptr<Expr> expr_in_break, std::vector<Attribute> outer_attribs, location_t locus) : outer_attrs (std::move (outer_attribs)), label (std::move (break_label)), break_expr (std::move (expr_in_break)), locus (locus) @@ -2922,7 +2982,13 @@ public: outer_attrs = std::move (new_attrs); } - LoopLabel &get_label () { return label; } + LoopLabel &get_label_unchecked () { return label.value (); } + const LoopLabel &get_label_unchecked () const { return label.value (); } + + tl::optional<LoopLabel> &get_label () { return label; } + const tl::optional<LoopLabel> &get_label () const { return label; } + + Expr::Kind get_expr_kind () const override { return Expr::Kind::Break; } protected: /* Use covariance to implement clone function as returning this object rather @@ -2938,6 +3004,10 @@ class RangeExpr : public ExprWithoutBlock { location_t locus; + // Some visitors still check for attributes on RangeExprs, and they will need + // to be supported in the future - so keep that for now + std::vector<Attribute> empty_attributes = {}; + protected: // outer attributes not allowed before range expressions RangeExpr (location_t locus) : locus (locus) {} @@ -2947,15 +3017,13 @@ public: std::vector<Attribute> &get_outer_attrs () override final { - // RangeExpr cannot have any outer attributes - rust_assert (false); + return empty_attributes; } // should never be called - error if called - void set_outer_attrs (std::vector<Attribute> /* new_attrs */) override - { - rust_assert (false); - } + void set_outer_attrs (std::vector<Attribute> /* new_attrs */) override {} + + Expr::Kind get_expr_kind () const override { return Expr::Kind::Range; } }; // Range from (inclusive) and to (exclusive) expression AST node object @@ -3404,6 +3472,8 @@ public: return *expr; } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Box; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3491,6 +3561,8 @@ public: outer_attrs = std::move (new_attrs); } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Return; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3573,6 +3645,8 @@ public: outer_attrs = std::move (new_attrs); } + Expr::Kind get_expr_kind () const override { return Expr::Kind::UnsafeBlock; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3588,7 +3662,7 @@ class BaseLoopExpr : public ExprWithBlock protected: // protected to allow subclasses better use of them std::vector<Attribute> outer_attrs; - LoopLabel loop_label; + tl::optional<LoopLabel> loop_label; std::unique_ptr<BlockExpr> loop_block; private: @@ -3597,7 +3671,7 @@ private: protected: // Constructor for BaseLoopExpr BaseLoopExpr (std::unique_ptr<BlockExpr> loop_block, location_t locus, - LoopLabel loop_label = LoopLabel::error (), + tl::optional<LoopLabel> loop_label = tl::nullopt, std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) : outer_attrs (std::move (outer_attribs)), @@ -3637,9 +3711,10 @@ protected: BaseLoopExpr &operator= (BaseLoopExpr &&other) = default; public: - bool has_loop_label () const { return !loop_label.is_error (); } + bool has_loop_label () const { return loop_label.has_value (); } - LoopLabel &get_loop_label () { return loop_label; } + LoopLabel &get_loop_label () { return loop_label.value (); } + const LoopLabel &get_loop_label () const { return loop_label.value (); } location_t get_locus () const override final { return locus; } @@ -3661,6 +3736,18 @@ public: { outer_attrs = std::move (new_attrs); } + + Expr::Kind get_expr_kind () const override { return Expr::Kind::Loop; } + + enum class Kind + { + Loop, + While, + WhileLet, + For + }; + + virtual Kind get_loop_kind () const = 0; }; // 'Loop' expression (i.e. the infinite loop) AST node @@ -3671,7 +3758,7 @@ public: // Constructor for LoopExpr LoopExpr (std::unique_ptr<BlockExpr> loop_block, location_t locus, - LoopLabel loop_label = LoopLabel::error (), + tl::optional<LoopLabel> loop_label = tl::nullopt, std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) : BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label), std::move (outer_attribs)) @@ -3679,6 +3766,11 @@ public: void accept_vis (ASTVisitor &vis) override; + BaseLoopExpr::Kind get_loop_kind () const override + { + return BaseLoopExpr::Kind::Loop; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3699,7 +3791,7 @@ public: // Constructor for while loop with loop label WhileLoopExpr (std::unique_ptr<Expr> loop_condition, std::unique_ptr<BlockExpr> loop_block, location_t locus, - LoopLabel loop_label = LoopLabel::error (), + tl::optional<LoopLabel> loop_label = tl::nullopt, std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) : BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label), @@ -3737,6 +3829,11 @@ public: return *condition; } + BaseLoopExpr::Kind get_loop_kind () const override + { + return BaseLoopExpr::Kind::While; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3760,7 +3857,7 @@ public: WhileLetLoopExpr (std::vector<std::unique_ptr<Pattern> > match_arm_patterns, std::unique_ptr<Expr> scrutinee, std::unique_ptr<BlockExpr> loop_block, location_t locus, - LoopLabel loop_label = LoopLabel::error (), + tl::optional<LoopLabel> loop_label = tl::nullopt, std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) : BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label), @@ -3820,6 +3917,11 @@ public: return match_arm_patterns; } + BaseLoopExpr::Kind get_loop_kind () const override + { + return BaseLoopExpr::Kind::WhileLet; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3842,7 +3944,7 @@ public: ForLoopExpr (std::unique_ptr<Pattern> loop_pattern, std::unique_ptr<Expr> iterator_expr, std::unique_ptr<BlockExpr> loop_body, location_t locus, - LoopLabel loop_label = LoopLabel::error (), + tl::optional<LoopLabel> loop_label = tl::nullopt, std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) : BaseLoopExpr (std::move (loop_body), locus, std::move (loop_label), std::move (outer_attribs)), @@ -3889,6 +3991,11 @@ public: return *pattern; } + BaseLoopExpr::Kind get_loop_kind () const override + { + return BaseLoopExpr::Kind::For; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -4012,6 +4119,8 @@ public: const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } + Expr::Kind get_expr_kind () const override { return Expr::Kind::If; } + protected: // Base clone function but still concrete as concrete base class virtual IfExpr *clone_if_expr_impl () const { return new IfExpr (*this); } @@ -4206,6 +4315,8 @@ public: const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } + Expr::Kind get_expr_kind () const override { return Expr::Kind::IfLet; } + protected: /* Use covariance to implement clone function as returning this object rather * than base (or rather this or any derived object) */ @@ -4535,6 +4646,8 @@ public: const std::vector<MatchCase> &get_match_cases () const { return match_arms; } std::vector<MatchCase> &get_match_cases () { return match_arms; } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Match; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -4614,6 +4727,8 @@ public: outer_attrs = std::move (new_attrs); } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Await; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -4696,6 +4811,8 @@ public: outer_attrs = std::move (new_attrs); } + Expr::Kind get_expr_kind () const override { return Expr::Kind::AsyncBlock; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -4768,9 +4885,31 @@ struct InlineAsmRegOrRegClass location_t locus; }; -struct InlineAsmOperand +struct LlvmOperand { - enum RegisterType + std::string constraint; + std::unique_ptr<Expr> expr; + + LlvmOperand (std::string constraint, std::unique_ptr<Expr> &&expr) + : constraint (constraint), expr (std::move (expr)) + {} + + LlvmOperand (const LlvmOperand &other) + : constraint (other.constraint), expr (other.expr->clone_expr ()) + {} + LlvmOperand &operator= (const LlvmOperand &other) + { + constraint = other.constraint; + expr = other.expr->clone_expr (); + + return *this; + } +}; + +class InlineAsmOperand +{ +public: + enum class RegisterType { In, Out, @@ -4781,8 +4920,24 @@ struct InlineAsmOperand Label, }; - struct In + class Register + { + public: + Register () {} + virtual ~Register () = default; + + std::unique_ptr<Register> clone () const + { + return std::unique_ptr<Register> (clone_impl ()); + } + + protected: + virtual Register *clone_impl () const = 0; + }; + + class In : public Register { + public: tl::optional<InlineAsmRegOrRegClass> reg; std::unique_ptr<Expr> expr; @@ -4793,24 +4948,28 @@ struct InlineAsmOperand rust_assert (this->expr != nullptr); } - In (const struct In &other) + In (const In &other) { reg = other.reg; expr = other.expr->clone_expr (); } - In operator= (const struct In &other) + In operator= (const In &other) { reg = other.reg; expr = other.expr->clone_expr (); return *this; } + + private: + In *clone_impl () const { return new In (*this); } }; - struct Out + class Out : public Register { + public: tl::optional<InlineAsmRegOrRegClass> reg; bool late; std::unique_ptr<Expr> expr; // can be null @@ -4822,24 +4981,28 @@ struct InlineAsmOperand rust_assert (this->expr != nullptr); } - Out (const struct Out &other) + Out (const Out &other) { reg = other.reg; late = other.late; expr = other.expr->clone_expr (); } - Out operator= (const struct Out &other) + Out operator= (const Out &other) { reg = other.reg; late = other.late; expr = other.expr->clone_expr (); return *this; } + + private: + Out *clone_impl () const { return new Out (*this); } }; - struct InOut + class InOut : public Register { + public: tl::optional<InlineAsmRegOrRegClass> reg; bool late; std::unique_ptr<Expr> expr; // this can't be null @@ -4851,14 +5014,14 @@ struct InlineAsmOperand rust_assert (this->expr != nullptr); } - InOut (const struct InOut &other) + InOut (const InOut &other) { reg = other.reg; late = other.late; expr = other.expr->clone_expr (); } - InOut operator= (const struct InOut &other) + InOut operator= (const InOut &other) { reg = other.reg; late = other.late; @@ -4866,10 +5029,14 @@ struct InlineAsmOperand return *this; } + + private: + InOut *clone_impl () const { return new InOut (*this); } }; - struct SplitInOut + class SplitInOut : public Register { + public: tl::optional<InlineAsmRegOrRegClass> reg; bool late; std::unique_ptr<Expr> in_expr; @@ -4884,7 +5051,7 @@ struct InlineAsmOperand rust_assert (this->out_expr != nullptr); } - SplitInOut (const struct SplitInOut &other) + SplitInOut (const SplitInOut &other) { reg = other.reg; late = other.late; @@ -4892,7 +5059,7 @@ struct InlineAsmOperand out_expr = other.out_expr->clone_expr (); } - SplitInOut operator= (const struct SplitInOut &other) + SplitInOut operator= (const SplitInOut &other) { reg = other.reg; late = other.late; @@ -4901,35 +5068,47 @@ struct InlineAsmOperand return *this; } + + private: + SplitInOut *clone_impl () const { return new SplitInOut (*this); } }; - struct Const + class Const : public Register { + public: AnonConst anon_const; + + private: + Const *clone_impl () const { return new Const (*this); } }; - struct Sym + class Sym : public Register { + public: std::unique_ptr<Expr> expr; Sym (std::unique_ptr<Expr> expr) : expr (std::move (expr)) { rust_assert (this->expr != nullptr); } - Sym (const struct Sym &other) + Sym (const Sym &other) { expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); } - Sym operator= (const struct Sym &other) + Sym operator= (const Sym &other) { expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); return *this; } + + private: + Sym *clone_impl () const { return new Sym (*this); } }; - struct Label + class Label : public Register { + public: std::string label_name; std::unique_ptr<Expr> expr; @@ -4940,86 +5119,137 @@ struct InlineAsmOperand if (label_name.has_value ()) this->label_name = label_name.value (); } - Label (const struct Label &other) + Label (const Label &other) { expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); } - Label operator= (const struct Label &other) + Label operator= (const Label &other) { expr = std::unique_ptr<Expr> (other.expr->clone_expr ()); return *this; } - }; - RegisterType register_type; - - tl::optional<struct In> in; - tl::optional<struct Out> out; - tl::optional<struct InOut> in_out; - tl::optional<struct SplitInOut> split_in_out; - tl::optional<struct Const> cnst; - tl::optional<struct Sym> sym; - tl::optional<struct Label> label; + private: + Label *clone_impl () const { return new Label (*this); } + }; - InlineAsmOperand () {} InlineAsmOperand (const InlineAsmOperand &other) - : in (other.in), out (other.out), in_out (other.in_out), - split_in_out (other.split_in_out), cnst (other.cnst), sym (other.sym) + : register_type (other.register_type), locus (other.locus), + reg (other.reg->clone ()) {} - void set_in (const tl::optional<struct In> ®) - { - this->register_type = In; + InlineAsmOperand (const In ®, location_t locus) + : register_type (RegisterType::In), locus (locus), reg (new In (reg)) + {} + InlineAsmOperand (const Out ®, location_t locus) + : register_type (RegisterType::Out), locus (locus), reg (new Out (reg)) + {} + InlineAsmOperand (const InOut ®, location_t locus) + : register_type (RegisterType::InOut), locus (locus), reg (new InOut (reg)) + {} + InlineAsmOperand (const SplitInOut ®, location_t locus) + : register_type (RegisterType::SplitInOut), locus (locus), + reg (new SplitInOut (reg)) + {} + InlineAsmOperand (const Const ®, location_t locus) + : register_type (RegisterType::Const), locus (locus), reg (new Const (reg)) + {} + InlineAsmOperand (const Sym ®, location_t locus) + : register_type (RegisterType::Sym), locus (locus), reg (new Sym (reg)) + {} + InlineAsmOperand (const Label ®, location_t locus) + : register_type (RegisterType::Label), locus (locus), reg (new Label (reg)) + {} - if (reg.has_value ()) - this->in = reg.value (); - } + location_t get_locus () const { return locus; } + RegisterType get_register_type () const { return register_type; } - void set_out (const tl::optional<struct Out> ®) + // Potentially fail immediately if you don't use get_register_type() to + // inspect the RegisterType first before calling the following functions Check + // first + In &get_in () + { + rust_assert (register_type == RegisterType::In); + return static_cast<In &> (*reg); + } + const In &get_in () const { - this->register_type = Out; + rust_assert (register_type == RegisterType::In); + return static_cast<const In &> (*reg); + } - if (reg.has_value ()) - this->out = reg.value (); + Out &get_out () + { + rust_assert (register_type == RegisterType::Out); + return static_cast<Out &> (*reg); + } + const Out &get_out () const + { + rust_assert (register_type == RegisterType::Out); + return static_cast<const Out &> (*reg); } - void set_in_out (const tl::optional<struct InOut> ®) + InOut &get_in_out () { - this->register_type = InOut; - if (reg.has_value ()) - this->in_out = reg.value (); + rust_assert (register_type == RegisterType::InOut); + return static_cast<InOut &> (*reg); + } + const InOut &get_in_out () const + { + rust_assert (register_type == RegisterType::InOut); + return static_cast<const InOut &> (*reg); } - void set_split_in_out (const tl::optional<struct SplitInOut> ®) + SplitInOut &get_split_in_out () { - this->register_type = SplitInOut; - if (reg.has_value ()) - this->split_in_out = reg.value (); + rust_assert (register_type == RegisterType::SplitInOut); + return static_cast<SplitInOut &> (*reg); + } + const SplitInOut &get_split_in_out () const + { + rust_assert (register_type == RegisterType::SplitInOut); + return static_cast<const SplitInOut &> (*reg); } - void set_cnst (const tl::optional<struct Const> ®) + Const &get_const () + { + rust_assert (register_type == RegisterType::Const); + return static_cast<Const &> (*reg); + } + const Const &get_const () const { - this->register_type = Const; - if (reg.has_value ()) - this->cnst = reg.value (); + rust_assert (register_type == RegisterType::Const); + return static_cast<Const &> (*reg); } - void set_sym (const tl::optional<struct Sym> ®) + Sym &get_sym () + { + rust_assert (register_type == RegisterType::Sym); + return static_cast<Sym &> (*reg); + } + const Sym &get_sym () const { - this->register_type = Sym; - if (reg.has_value ()) - this->sym = reg.value (); + rust_assert (register_type == RegisterType::Sym); + return static_cast<const Sym &> (*reg); } - void set_label (const tl::optional<struct Label> ®) + Label &get_label () { - this->register_type = Label; - if (reg.has_value ()) - this->label = reg.value (); + rust_assert (register_type == RegisterType::Label); + return static_cast<Label &> (*reg); } + const Label &get_label () const + { + rust_assert (register_type == RegisterType::Label); + return static_cast<const Label &> (*reg); + } + +private: + RegisterType register_type; location_t locus; + std::unique_ptr<Register> reg; }; struct InlineAsmPlaceHolder @@ -5049,6 +5279,7 @@ struct TupleTemplateStr location_t loc; std::string symbol; + location_t get_locus () { return loc; } TupleTemplateStr (location_t loc, const std::string &symbol) : loc (loc), symbol (symbol) {} @@ -5117,6 +5348,79 @@ public: { return new InlineAsm (*this); } + + Expr::Kind get_expr_kind () const override { return Expr::Kind::InlineAsm; } +}; + +class LlvmInlineAsm : public ExprWithoutBlock +{ + // llvm_asm!("" : : "r"(&mut dummy) : "memory" : "volatile"); + // Asm, Outputs, Inputs, Clobbers, Options, + +public: + enum class Dialect + { + Att, + Intel, + }; + +private: + location_t locus; + std::vector<Attribute> outer_attrs; + std::vector<LlvmOperand> inputs; + std::vector<LlvmOperand> outputs; + std::vector<TupleTemplateStr> templates; + std::vector<TupleClobber> clobbers; + bool volatility; + bool align_stack; + Dialect dialect; + +public: + LlvmInlineAsm (location_t locus) : locus (locus) {} + + Dialect get_dialect () { return dialect; } + + location_t get_locus () const override { return locus; } + + void mark_for_strip () override {} + + bool is_marked_for_strip () const override { return false; } + + std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } + + void accept_vis (ASTVisitor &vis) override; + + std::string as_string () const override { return "InlineAsm AST Node"; } + + void set_outer_attrs (std::vector<Attribute> v) override { outer_attrs = v; } + + LlvmInlineAsm *clone_expr_without_block_impl () const override + { + return new LlvmInlineAsm (*this); + } + + std::vector<TupleTemplateStr> &get_templates () { return templates; } + + Expr::Kind get_expr_kind () const override + { + return Expr::Kind::LlvmInlineAsm; + } + + void set_align_stack (bool align_stack) { this->align_stack = align_stack; } + bool is_stack_aligned () { return align_stack; } + + void set_volatile (bool volatility) { this->volatility = volatility; } + bool is_volatile () { return volatility; } + + void set_dialect (Dialect dialect) { this->dialect = dialect; } + + void set_inputs (std::vector<LlvmOperand> operands) { inputs = operands; } + void set_outputs (std::vector<LlvmOperand> operands) { outputs = operands; } + + std::vector<LlvmOperand> &get_inputs () { return inputs; } + std::vector<LlvmOperand> &get_outputs () { return outputs; } + + std::vector<TupleClobber> &get_clobbers () { return clobbers; } }; } // namespace AST |