diff options
Diffstat (limited to 'gcc/rust/ast/rust-expr.h')
| -rw-r--r-- | gcc/rust/ast/rust-expr.h | 861 |
1 files changed, 732 insertions, 129 deletions
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index cff09fe..3c36238 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -1,6 +1,7 @@ #ifndef RUST_AST_EXPR_H #define RUST_AST_EXPR_H +#include "optional.h" #include "rust-ast.h" #include "rust-common.h" #include "rust-path.h" @@ -31,11 +32,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; } @@ -187,9 +183,13 @@ public: AttrInputMacro (AttrInputMacro &&oth) : macro (std::move (oth.macro)) {} - void operator= (const AttrInputMacro &oth); + AttrInputMacro &operator= (const AttrInputMacro &oth); - void operator= (AttrInputMacro &&oth) { macro = std::move (oth.macro); } + AttrInputMacro &operator= (AttrInputMacro &&oth) + { + macro = std::move (oth.macro); + return *this; + } std::string as_string () const override; @@ -249,40 +249,60 @@ protected: } }; -// more generic meta item "path = lit" form -class MetaItemPathLit : public MetaItem +// more generic meta item "path = expr" form +class MetaItemPathExpr : public MetaItem { SimplePath path; - LiteralExpr lit; + std::unique_ptr<Expr> expr; public: - MetaItemPathLit (SimplePath path, LiteralExpr lit_expr) - : path (std::move (path)), lit (std::move (lit_expr)) + MetaItemPathExpr (SimplePath path, std::unique_ptr<Expr> expr) + : path (std::move (path)), expr (std::move (expr)) + {} + + MetaItemPathExpr (const MetaItemPathExpr &other) + : MetaItem (other), path (other.path), expr (other.expr->clone_expr ()) {} + MetaItemPathExpr (MetaItemPathExpr &&) = default; + + MetaItemPathExpr &operator= (MetaItemPathExpr &&) = default; + + MetaItemPathExpr operator= (const MetaItemPathExpr &other) + { + MetaItem::operator= (other); + path = other.path; + expr = other.expr->clone_expr (); + return *this; + } + SimplePath get_path () const { return path; } SimplePath &get_path () { return path; } - LiteralExpr get_literal () const { return lit; } + Expr &get_expr () { return *expr; } - LiteralExpr &get_literal () { return lit; } + std::unique_ptr<Expr> &get_expr_ptr () { return expr; } std::string as_string () const override { - return path.as_string () + " = " + lit.as_string (); + return path.as_string () + " = " + expr->as_string (); } MetaItem::ItemKind get_item_kind () const override { - return MetaItem::ItemKind::PathLit; + return MetaItem::ItemKind::PathExpr; } - // There are two Locations in MetaItemPathLit (path and lit_expr), + // There are two Locations in MetaItemPathExpr (path and expr), // we have no idea use which of them, just simply return UNKNOWN_LOCATION // now. // Maybe we will figure out when we really need the location in the future. - location_t get_locus () const override { return UNKNOWN_LOCATION; } + location_t get_locus () const override + { + rust_unreachable (); + return UNKNOWN_LOCATION; + } void accept_vis (ASTVisitor &vis) override; @@ -294,9 +314,9 @@ public: protected: // Use covariance to implement clone function as returning this type - MetaItemPathLit *clone_meta_item_inner_impl () const override + MetaItemPathExpr *clone_meta_item_inner_impl () const override { - return new MetaItemPathLit (*this); + return new MetaItemPathExpr (*this); } }; @@ -400,6 +420,14 @@ public: return *main_or_left_expr; } + std::unique_ptr<Expr> &get_borrowed_expr_ptr () + { + rust_assert (main_or_left_expr != nullptr); + return main_or_left_expr; + } + + bool has_borrow_expr () const { return main_or_left_expr != nullptr; } + bool get_is_mut () const { return mutability == Mutability::Mut; } Mutability get_mutability () const { return mutability; } @@ -439,6 +467,12 @@ public: return *main_or_left_expr; } + std::unique_ptr<Expr> &get_dereferenced_expr_ptr () + { + rust_assert (main_or_left_expr != nullptr); + return main_or_left_expr; + } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Dereference; } protected: @@ -472,6 +506,12 @@ public: return *main_or_left_expr; } + std::unique_ptr<Expr> &get_propagating_expr_ptr () + { + rust_assert (main_or_left_expr != nullptr); + return main_or_left_expr; + } + Expr::Kind get_expr_kind () const override { return Expr::Kind::ErrorPropagation; @@ -520,6 +560,12 @@ public: return *main_or_left_expr; } + std::unique_ptr<Expr> &get_negated_expr_ptr () + { + rust_assert (main_or_left_expr != nullptr); + return main_or_left_expr; + } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Negation; } protected: @@ -849,6 +895,12 @@ public: return *main_or_left_expr; } + std::unique_ptr<Expr> &get_casted_expr_ptr () + { + rust_assert (main_or_left_expr != nullptr); + return main_or_left_expr; + } + // TODO: is this better? Or is a "vis_block" better? TypeNoBounds &get_type_to_cast_to () { @@ -856,6 +908,12 @@ public: return *type_to_convert_to; } + std::unique_ptr<TypeNoBounds> &get_type_to_cast_to_ptr () + { + rust_assert (type_to_convert_to != nullptr); + return type_to_convert_to; + } + Expr::Kind get_expr_kind () const override { return Expr::Kind::TypeCast; } protected: @@ -1165,11 +1223,11 @@ protected: // Value array elements class ArrayElemsValues : public ArrayElems { - std::vector<std::unique_ptr<Expr> > values; + std::vector<std::unique_ptr<Expr>> values; location_t locus; public: - ArrayElemsValues (std::vector<std::unique_ptr<Expr> > elems, location_t locus) + ArrayElemsValues (std::vector<std::unique_ptr<Expr>> elems, location_t locus) : ArrayElems (), values (std::move (elems)), locus (locus) {} @@ -1197,14 +1255,16 @@ public: std::string as_string () const override; + location_t get_locus () const { return locus; } + void accept_vis (ASTVisitor &vis) override; // TODO: this mutable getter seems really dodgy. Think up better way. - const std::vector<std::unique_ptr<Expr> > &get_values () const + const std::vector<std::unique_ptr<Expr>> &get_values () const { return values; } - std::vector<std::unique_ptr<Expr> > &get_values () { return values; } + std::vector<std::unique_ptr<Expr>> &get_values () { return values; } size_t get_num_values () const { return values.size (); } @@ -1219,6 +1279,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; @@ -1251,6 +1313,8 @@ public: std::string as_string () const override; + location_t get_locus () const { return locus; } + void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? @@ -1260,6 +1324,12 @@ public: return *elem_to_copy; } + std::unique_ptr<Expr> &get_elem_to_copy_ptr () + { + rust_assert (elem_to_copy != nullptr); + return elem_to_copy; + } + // TODO: is this better? Or is a "vis_block" better? Expr &get_num_copies () { @@ -1267,6 +1337,12 @@ public: return *num_copies; } + std::unique_ptr<Expr> &get_num_copies_ptr () + { + rust_assert (num_copies != nullptr); + return num_copies; + } + protected: ArrayElemsCopied *clone_array_elems_impl () const override { @@ -1446,6 +1522,12 @@ public: return *array_expr; } + std::unique_ptr<Expr> &get_array_expr_ptr () + { + rust_assert (array_expr != nullptr); + return array_expr; + } + // TODO: is this better? Or is a "vis_block" better? Expr &get_index_expr () { @@ -1453,6 +1535,12 @@ public: return *index_expr; } + std::unique_ptr<Expr> &get_index_expr_ptr () + { + rust_assert (index_expr != nullptr); + return index_expr; + } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } @@ -1477,7 +1565,7 @@ class TupleExpr : public ExprWithoutBlock { std::vector<Attribute> outer_attrs; std::vector<Attribute> inner_attrs; - std::vector<std::unique_ptr<Expr> > tuple_elems; + std::vector<std::unique_ptr<Expr>> tuple_elems; location_t locus; // TODO: find another way to store this to save memory? @@ -1497,7 +1585,7 @@ public: outer_attrs = std::move (new_attrs); } - TupleExpr (std::vector<std::unique_ptr<Expr> > tuple_elements, + TupleExpr (std::vector<std::unique_ptr<Expr>> tuple_elements, std::vector<Attribute> inner_attribs, std::vector<Attribute> outer_attribs, location_t locus) : outer_attrs (std::move (outer_attribs)), @@ -1548,14 +1636,11 @@ public: bool is_marked_for_strip () const override { return marked_for_strip; } // TODO: this mutable getter seems really dodgy. Think up better way. - const std::vector<std::unique_ptr<Expr> > &get_tuple_elems () const - { - return tuple_elems; - } - std::vector<std::unique_ptr<Expr> > &get_tuple_elems () + const std::vector<std::unique_ptr<Expr>> &get_tuple_elems () const { return tuple_elems; } + std::vector<std::unique_ptr<Expr>> &get_tuple_elems () { return tuple_elems; } bool is_unit () const { return tuple_elems.size () == 0; } @@ -1580,6 +1665,7 @@ class TupleIndexExpr : public ExprWithoutBlock TupleIndex tuple_index; location_t locus; + bool to_strip; // i.e. pair.0 @@ -1591,13 +1677,15 @@ public: TupleIndexExpr (std::unique_ptr<Expr> tuple_expr, TupleIndex index, std::vector<Attribute> outer_attribs, location_t locus) : outer_attrs (std::move (outer_attribs)), - tuple_expr (std::move (tuple_expr)), tuple_index (index), locus (locus) + tuple_expr (std::move (tuple_expr)), tuple_index (index), locus (locus), + to_strip (false) {} // Copy constructor requires a clone for tuple_expr TupleIndexExpr (TupleIndexExpr const &other) : ExprWithoutBlock (other), outer_attrs (other.outer_attrs), - tuple_index (other.tuple_index), locus (other.locus) + tuple_index (other.tuple_index), locus (other.locus), + to_strip (other.to_strip) { // guard to prevent null dereference (only required if error state) if (other.tuple_expr != nullptr) @@ -1611,6 +1699,7 @@ public: tuple_index = other.tuple_index; locus = other.locus; outer_attrs = other.outer_attrs; + to_strip = other.to_strip; // guard to prevent null dereference (only required if error state) if (other.tuple_expr != nullptr) @@ -1630,8 +1719,8 @@ public: void accept_vis (ASTVisitor &vis) override; // Invalid if tuple expr is null, so base stripping on that. - void mark_for_strip () override { tuple_expr = nullptr; } - bool is_marked_for_strip () const override { return tuple_expr == nullptr; } + void mark_for_strip () override { to_strip = true; } + bool is_marked_for_strip () const override { return to_strip; } // TODO: is this better? Or is a "vis_block" better? Expr &get_tuple_expr () @@ -1640,6 +1729,12 @@ public: return *tuple_expr; } + std::unique_ptr<Expr> &get_tuple_expr_ptr () + { + rust_assert (tuple_expr != nullptr); + return tuple_expr; + } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } @@ -1780,12 +1875,20 @@ public: std::string as_string () const; + location_t get_locus () const { return locus; } + // TODO: is this better? Or is a "vis_block" better? Expr &get_base_struct () { rust_assert (base_struct != nullptr); return *base_struct; } + + std::unique_ptr<Expr> &get_base_struct_ptr () + { + rust_assert (base_struct != nullptr); + return base_struct; + } }; /* Base AST node for a single struct expression field (in struct instance @@ -1902,6 +2005,12 @@ public: rust_assert (value != nullptr); return *value; } + + std::unique_ptr<Expr> &get_value_ptr () + { + rust_assert (value != nullptr); + return value; + } }; // Identifier and value variant of StructExprField AST node @@ -1977,7 +2086,7 @@ protected: class StructExprStructFields : public StructExprStruct { // std::vector<StructExprField> fields; - std::vector<std::unique_ptr<StructExprField> > fields; + std::vector<std::unique_ptr<StructExprField>> fields; // bool has_struct_base; StructBase struct_base; @@ -1990,8 +2099,8 @@ public: // Constructor for StructExprStructFields when no struct base is used StructExprStructFields ( PathInExpression struct_path, - std::vector<std::unique_ptr<StructExprField> > expr_fields, - location_t locus, StructBase base_struct = StructBase::error (), + std::vector<std::unique_ptr<StructExprField>> expr_fields, location_t locus, + StructBase base_struct = StructBase::error (), std::vector<Attribute> inner_attribs = std::vector<Attribute> (), std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) : StructExprStruct (std::move (struct_path), std::move (inner_attribs), @@ -2028,11 +2137,11 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: this mutable getter seems really dodgy. Think up better way. - std::vector<std::unique_ptr<StructExprField> > &get_fields () + std::vector<std::unique_ptr<StructExprField>> &get_fields () { return fields; } - const std::vector<std::unique_ptr<StructExprField> > &get_fields () const + const std::vector<std::unique_ptr<StructExprField>> &get_fields () const { return fields; } @@ -2089,7 +2198,7 @@ class CallExpr : public ExprWithoutBlock { std::vector<Attribute> outer_attrs; std::unique_ptr<Expr> function; - std::vector<std::unique_ptr<Expr> > params; + std::vector<std::unique_ptr<Expr>> params; location_t locus; public: @@ -2098,7 +2207,7 @@ public: std::string as_string () const override; CallExpr (std::unique_ptr<Expr> function_expr, - std::vector<std::unique_ptr<Expr> > function_params, + std::vector<std::unique_ptr<Expr>> function_params, std::vector<Attribute> outer_attribs, location_t locus) : outer_attrs (std::move (outer_attribs)), function (std::move (function_expr)), @@ -2155,11 +2264,11 @@ public: bool is_marked_for_strip () const override { return function == nullptr; } // TODO: this mutable getter seems really dodgy. Think up better way. - const std::vector<std::unique_ptr<Expr> > &get_params () const + const std::vector<std::unique_ptr<Expr>> &get_params () const { return params; } - std::vector<std::unique_ptr<Expr> > &get_params () { return params; } + std::vector<std::unique_ptr<Expr>> &get_params () { return params; } // TODO: is this better? Or is a "vis_block" better? Expr &get_function_expr () @@ -2195,7 +2304,7 @@ class MethodCallExpr : public ExprWithoutBlock std::vector<Attribute> outer_attrs; std::unique_ptr<Expr> receiver; PathExprSegment method_name; - std::vector<std::unique_ptr<Expr> > params; + std::vector<std::unique_ptr<Expr>> params; location_t locus; public: @@ -2203,7 +2312,7 @@ public: MethodCallExpr (std::unique_ptr<Expr> call_receiver, PathExprSegment method_path, - std::vector<std::unique_ptr<Expr> > method_params, + std::vector<std::unique_ptr<Expr>> method_params, std::vector<Attribute> outer_attribs, location_t locus) : outer_attrs (std::move (outer_attribs)), receiver (std::move (call_receiver)), @@ -2259,11 +2368,11 @@ public: bool is_marked_for_strip () const override { return receiver == nullptr; } // TODO: this mutable getter seems really dodgy. Think up better way. - const std::vector<std::unique_ptr<Expr> > &get_params () const + const std::vector<std::unique_ptr<Expr>> &get_params () const { return params; } - std::vector<std::unique_ptr<Expr> > &get_params () { return params; } + std::vector<std::unique_ptr<Expr>> &get_params () { return params; } // TODO: is this better? Or is a "vis_block" better? Expr &get_receiver_expr () @@ -2272,6 +2381,12 @@ public: return *receiver; } + std::unique_ptr<Expr> &get_receiver_expr_ptr () + { + rust_assert (receiver != nullptr); + return receiver; + } + const PathExprSegment &get_method_name () const { return method_name; } PathExprSegment &get_method_name () { return method_name; } @@ -2360,6 +2475,12 @@ public: return *receiver; } + std::unique_ptr<Expr> &get_receiver_expr_ptr () + { + rust_assert (receiver != nullptr); + return receiver; + } + Identifier get_field_name () const { return field; } const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } @@ -2459,6 +2580,12 @@ public: return *pattern; } + std::unique_ptr<Pattern> &get_pattern_ptr () + { + rust_assert (pattern != nullptr); + return pattern; + } + Type &get_type () { rust_assert (has_type_given ()); @@ -2509,6 +2636,9 @@ public: bool get_has_move () const { return has_move; } Expr::Kind get_expr_kind () const override { return Expr::Kind::Closure; } + + virtual Expr &get_definition_expr () = 0; + virtual std::unique_ptr<Expr> &get_definition_expr_ptr () = 0; }; // Represents a non-type-specified closure expression AST node @@ -2568,12 +2698,18 @@ public: return closure_inner == nullptr; } - Expr &get_definition_expr () + Expr &get_definition_expr () override { rust_assert (closure_inner != nullptr); return *closure_inner; } + std::unique_ptr<Expr> &get_definition_expr_ptr () override + { + rust_assert (closure_inner != nullptr); + return closure_inner; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -2588,9 +2724,9 @@ class BlockExpr : public ExprWithBlock { std::vector<Attribute> outer_attrs; std::vector<Attribute> inner_attrs; - std::vector<std::unique_ptr<Stmt> > statements; + 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; @@ -2604,11 +2740,12 @@ public: // Returns whether the block contains a final expression. bool has_tail_expr () const { return expr != nullptr; } - BlockExpr (std::vector<std::unique_ptr<Stmt> > block_statements, + 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)), @@ -2682,11 +2819,11 @@ public: const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; } std::vector<Attribute> &get_inner_attrs () { return inner_attrs; } - const std::vector<std::unique_ptr<Stmt> > &get_statements () const + const std::vector<std::unique_ptr<Stmt>> &get_statements () const { return statements; } - std::vector<std::unique_ptr<Stmt> > &get_statements () { return statements; } + std::vector<std::unique_ptr<Stmt>> &get_statements () { return statements; } // TODO: is this better? Or is a "vis_block" better? Expr &get_tail_expr () @@ -2727,8 +2864,8 @@ 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; } @@ -2748,13 +2885,163 @@ protected: } }; +class AnonConst : public ExprWithBlock +{ +public: + enum class Kind + { + Explicit, + DeferredInference, + }; + + AnonConst (std::unique_ptr<Expr> &&expr, location_t locus = UNKNOWN_LOCATION) + : ExprWithBlock (), locus (locus), kind (Kind::Explicit), + expr (std::move (expr)) + { + rust_assert (this->expr.value ()); + } + + AnonConst (location_t locus = UNKNOWN_LOCATION) + : ExprWithBlock (), locus (locus), kind (Kind::DeferredInference), + expr (tl::nullopt) + {} + + AnonConst (const AnonConst &other) + { + node_id = other.node_id; + locus = other.locus; + kind = other.kind; + + if (other.expr) + expr = other.expr.value ()->clone_expr (); + } + + AnonConst operator= (const AnonConst &other) + { + node_id = other.node_id; + locus = other.locus; + kind = other.kind; + + if (other.expr) + expr = other.expr.value ()->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 () + { + rust_assert (expr.has_value ()); + return *expr.value (); + } + + std::unique_ptr<Expr> &get_inner_expr_ptr () + { + rust_assert (expr.has_value ()); + return expr.value (); + } + + 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; + + bool is_deferred () const { return kind == Kind::DeferredInference; } + +private: + location_t locus; + Kind kind; + tl::optional<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 { // TODO: spec says typenobounds std::unique_ptr<Type> return_type; - std::unique_ptr<BlockExpr> - expr; // only used because may be polymorphic in future + std::unique_ptr<Expr> expr; // only used because may be polymorphic in future public: std::string as_string () const override; @@ -2778,7 +3065,7 @@ public: { // guard to prevent null dereference (only required if error state) if (other.expr != nullptr) - expr = other.expr->clone_block_expr (); + expr = other.expr->clone_expr (); if (other.return_type != nullptr) return_type = other.return_type->clone_type (); } @@ -2793,7 +3080,7 @@ public: // guard to prevent null dereference (only required if error state) if (other.expr != nullptr) - expr = other.expr->clone_block_expr (); + expr = other.expr->clone_expr (); else expr = nullptr; if (other.return_type != nullptr) @@ -2816,12 +3103,19 @@ public: bool is_marked_for_strip () const override { return expr == nullptr; } // TODO: is this better? Or is a "vis_block" better? - BlockExpr &get_definition_block () + Expr &get_definition_expr () override { rust_assert (expr != nullptr); return *expr; } + std::unique_ptr<Expr> &get_definition_expr_ptr () override + { + rust_assert (expr != nullptr); + + return expr; + } + // TODO: is this better? Or is a "vis_block" better? Type &get_return_type () { @@ -2848,7 +3142,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? @@ -2858,11 +3152,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) {} @@ -2883,7 +3177,11 @@ 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; } @@ -2901,7 +3199,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; @@ -2912,14 +3210,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) @@ -2973,6 +3272,12 @@ public: return *break_expr; } + std::unique_ptr<Expr> &get_break_expr_ptr () + { + rust_assert (has_break_expr ()); + return break_expr; + } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } @@ -2981,7 +3286,11 @@ 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; } @@ -2999,6 +3308,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) {} @@ -3008,15 +3321,11 @@ 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; } }; @@ -3096,6 +3405,18 @@ public: return *to; } + std::unique_ptr<Expr> &get_from_expr_ptr () + { + rust_assert (from != nullptr); + return from; + } + + std::unique_ptr<Expr> &get_to_expr_ptr () + { + rust_assert (to != nullptr); + return to; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3157,6 +3478,12 @@ public: return *from; } + std::unique_ptr<Expr> &get_from_expr_ptr () + { + rust_assert (from != nullptr); + return from; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3219,6 +3546,12 @@ public: return *to; } + std::unique_ptr<Expr> &get_to_expr_ptr () + { + rust_assert (to != nullptr); + return to; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3332,6 +3665,18 @@ public: return *to; } + std::unique_ptr<Expr> &get_from_expr_ptr () + { + rust_assert (from != nullptr); + return from; + } + + std::unique_ptr<Expr> &get_to_expr_ptr () + { + rust_assert (to != nullptr); + return to; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3394,6 +3739,12 @@ public: return *to; } + std::unique_ptr<Expr> &get_to_expr_ptr () + { + rust_assert (to != nullptr); + return to; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ @@ -3467,6 +3818,12 @@ public: return *expr; } + std::unique_ptr<Expr> &get_boxed_expr_ptr () + { + rust_assert (expr != nullptr); + return expr; + } + Expr::Kind get_expr_kind () const override { return Expr::Kind::Box; } protected: @@ -3548,6 +3905,12 @@ public: return *return_expr; } + std::unique_ptr<Expr> &get_returned_expr_ptr () + { + rust_assert (return_expr != nullptr); + return return_expr; + } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } @@ -3567,6 +3930,83 @@ protected: } }; +// Try expression AST node representation +class TryExpr : public ExprWithBlock +{ + std::vector<Attribute> outer_attrs; + std::unique_ptr<BlockExpr> block_expr; + location_t locus; + + // TODO: find another way to store this to save memory? + bool marked_for_strip = false; + +public: + std::string as_string () const override; + + // Constructor for ReturnExpr. + TryExpr (std::unique_ptr<BlockExpr> block_expr, + std::vector<Attribute> outer_attribs, location_t locus) + : outer_attrs (std::move (outer_attribs)), + block_expr (std::move (block_expr)), locus (locus) + { + rust_assert (this->block_expr); + } + + // Copy constructor with clone + TryExpr (TryExpr const &other) + : ExprWithBlock (other), outer_attrs (other.outer_attrs), + block_expr (other.block_expr->clone_block_expr ()), locus (other.locus), + marked_for_strip (other.marked_for_strip) + {} + + // Overloaded assignment operator to clone return_expr pointer + TryExpr &operator= (TryExpr const &other) + { + ExprWithBlock::operator= (other); + locus = other.locus; + marked_for_strip = other.marked_for_strip; + outer_attrs = other.outer_attrs; + + block_expr = other.block_expr->clone_block_expr (); + + return *this; + } + + // move constructors + TryExpr (TryExpr &&other) = default; + TryExpr &operator= (TryExpr &&other) = default; + + location_t get_locus () const override final { return locus; } + + void accept_vis (ASTVisitor &vis) override; + + // Can't think of any invalid invariants, so store boolean. + void mark_for_strip () override { marked_for_strip = true; } + bool is_marked_for_strip () const override { return marked_for_strip; } + + // TODO: is this better? Or is a "vis_block" better? + BlockExpr &get_block_expr () { return *block_expr; } + std::unique_ptr<BlockExpr> &get_block_expr_ptr () { return block_expr; } + + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } + 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); + } + + Expr::Kind get_expr_kind () const override { return Expr::Kind::Try; } + +protected: + /* Use covariance to implement clone function as returning this object rather + * than base */ + TryExpr *clone_expr_with_block_impl () const override + { + return new TryExpr (*this); + } +}; + // Forward decl - defined in rust-macro.h class MacroInvocation; @@ -3632,6 +4072,12 @@ public: return *expr; } + std::unique_ptr<BlockExpr> &get_block_expr_ptr () + { + rust_assert (expr != nullptr); + return expr; + } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } @@ -3657,7 +4103,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: @@ -3666,7 +4112,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)), @@ -3706,9 +4152,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; } @@ -3723,6 +4170,12 @@ public: return *loop_block; } + std::unique_ptr<BlockExpr> &get_loop_block_ptr () + { + rust_assert (loop_block != nullptr); + return loop_block; + } + const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; } @@ -3752,7 +4205,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)) @@ -3785,7 +4238,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), @@ -3823,6 +4276,12 @@ public: return *condition; } + std::unique_ptr<Expr> &get_predicate_expr_ptr () + { + rust_assert (condition != nullptr); + return condition; + } + BaseLoopExpr::Kind get_loop_kind () const override { return BaseLoopExpr::Kind::While; @@ -3841,17 +4300,17 @@ protected: class WhileLetLoopExpr : public BaseLoopExpr { // MatchArmPatterns patterns; - std::vector<std::unique_ptr<Pattern> > match_arm_patterns; // inlined + std::vector<std::unique_ptr<Pattern>> match_arm_patterns; // inlined std::unique_ptr<Expr> scrutinee; public: std::string as_string () const override; // Constructor with a loop label - WhileLetLoopExpr (std::vector<std::unique_ptr<Pattern> > match_arm_patterns, + 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), @@ -3901,12 +4360,18 @@ public: return *scrutinee; } + std::unique_ptr<Expr> &get_scrutinee_expr_ptr () + { + rust_assert (scrutinee != nullptr); + return scrutinee; + } + // TODO: this mutable getter seems really dodgy. Think up better way. - const std::vector<std::unique_ptr<Pattern> > &get_patterns () const + const std::vector<std::unique_ptr<Pattern>> &get_patterns () const { return match_arm_patterns; } - std::vector<std::unique_ptr<Pattern> > &get_patterns () + std::vector<std::unique_ptr<Pattern>> &get_patterns () { return match_arm_patterns; } @@ -3938,7 +4403,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)), @@ -3978,6 +4443,12 @@ public: return *iterator_expr; } + std::unique_ptr<Expr> &get_iterator_expr_ptr () + { + rust_assert (iterator_expr != nullptr); + return iterator_expr; + } + // TODO: is this better? Or is a "vis_block" better? Pattern &get_pattern () { @@ -3985,6 +4456,12 @@ public: return *pattern; } + std::unique_ptr<Pattern> &get_pattern_ptr () + { + rust_assert (pattern != nullptr); + return pattern; + } + BaseLoopExpr::Kind get_loop_kind () const override { return BaseLoopExpr::Kind::For; @@ -4189,7 +4666,7 @@ protected: class IfLetExpr : public ExprWithBlock { std::vector<Attribute> outer_attrs; - std::vector<std::unique_ptr<Pattern> > match_arm_patterns; // inlined + std::vector<std::unique_ptr<Pattern>> match_arm_patterns; // inlined std::unique_ptr<Expr> value; std::unique_ptr<BlockExpr> if_block; location_t locus; @@ -4197,7 +4674,7 @@ class IfLetExpr : public ExprWithBlock public: std::string as_string () const override; - IfLetExpr (std::vector<std::unique_ptr<Pattern> > match_arm_patterns, + IfLetExpr (std::vector<std::unique_ptr<Pattern>> match_arm_patterns, std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, std::vector<Attribute> outer_attrs, location_t locus) : outer_attrs (std::move (outer_attrs)), @@ -4291,11 +4768,11 @@ public: } // TODO: this mutable getter seems really dodgy. Think up better way. - const std::vector<std::unique_ptr<Pattern> > &get_patterns () const + const std::vector<std::unique_ptr<Pattern>> &get_patterns () const { return match_arm_patterns; } - std::vector<std::unique_ptr<Pattern> > &get_patterns () + std::vector<std::unique_ptr<Pattern>> &get_patterns () { return match_arm_patterns; } @@ -4335,11 +4812,11 @@ class IfLetExprConseqElse : public IfLetExpr public: std::string as_string () const override; - IfLetExprConseqElse ( - std::vector<std::unique_ptr<Pattern> > match_arm_patterns, - std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, - std::unique_ptr<ExprWithBlock> else_block, - std::vector<Attribute> outer_attrs, location_t locus) + IfLetExprConseqElse (std::vector<std::unique_ptr<Pattern>> match_arm_patterns, + std::unique_ptr<Expr> value, + std::unique_ptr<BlockExpr> if_block, + std::unique_ptr<ExprWithBlock> else_block, + std::vector<Attribute> outer_attrs, location_t locus) : IfLetExpr (std::move (match_arm_patterns), std::move (value), std::move (if_block), std::move (outer_attrs), locus), else_block (std::move (else_block)) @@ -4392,7 +4869,7 @@ struct MatchArm private: std::vector<Attribute> outer_attrs; // MatchArmPatterns patterns; - std::vector<std::unique_ptr<Pattern> > match_arm_patterns; // inlined + std::vector<std::unique_ptr<Pattern>> match_arm_patterns; // inlined // bool has_match_arm_guard; // inlined from MatchArmGuard @@ -4405,7 +4882,7 @@ public: bool has_match_arm_guard () const { return guard_expr != nullptr; } // Constructor for match arm with a guard expression - MatchArm (std::vector<std::unique_ptr<Pattern> > match_arm_patterns, + MatchArm (std::vector<std::unique_ptr<Pattern>> match_arm_patterns, location_t locus, std::unique_ptr<Expr> guard_expr = nullptr, std::vector<Attribute> outer_attrs = std::vector<Attribute> ()) : outer_attrs (std::move (outer_attrs)), @@ -4457,7 +4934,7 @@ public: static MatchArm create_error () { location_t locus = UNDEF_LOCATION; - return MatchArm (std::vector<std::unique_ptr<Pattern> > (), locus); + return MatchArm (std::vector<std::unique_ptr<Pattern>> (), locus); } std::string as_string () const; @@ -4479,11 +4956,11 @@ public: const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } - const std::vector<std::unique_ptr<Pattern> > &get_patterns () const + const std::vector<std::unique_ptr<Pattern>> &get_patterns () const { return match_arm_patterns; } - std::vector<std::unique_ptr<Pattern> > &get_patterns () + std::vector<std::unique_ptr<Pattern>> &get_patterns () { return match_arm_patterns; } @@ -4637,6 +5114,12 @@ public: return *branch_value; } + std::unique_ptr<Expr> &get_scrutinee_expr_ptr () + { + rust_assert (branch_value != nullptr); + return branch_value; + } + const std::vector<MatchCase> &get_match_cases () const { return match_arms; } std::vector<MatchCase> &get_match_cases () { return match_arms; } @@ -4830,29 +5313,6 @@ enum class InlineAsmOption MAY_UNWIND = 1 << 8, }; -struct AnonConst -{ - 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; - } -}; - struct InlineAsmRegOrRegClass { enum Type @@ -4879,6 +5339,27 @@ struct InlineAsmRegOrRegClass location_t locus; }; +struct LlvmOperand +{ + 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: @@ -5241,6 +5722,8 @@ struct InlineAsmTemplatePiece struct TupleClobber { + TupleClobber (std::string symbol, location_t loc) : symbol (symbol), loc (loc) + {} // as gccrs still doesn't contain a symbol class I have put them as strings std::string symbol; location_t loc; @@ -5252,6 +5735,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) {} @@ -5260,6 +5744,20 @@ struct TupleTemplateStr // Inline Assembly Node class InlineAsm : public ExprWithoutBlock { +public: + enum class Option + { + 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, + }; + private: location_t locus; // TODO: Not sure how outer_attrs plays with InlineAsm, I put it here in order @@ -5283,7 +5781,7 @@ public: std::map<std::string, int> named_args; std::set<int> reg_args; std::vector<TupleClobber> clobber_abi; - std::set<InlineAsmOption> options; + std::set<InlineAsm::Option> options; std::vector<location_t> line_spans; @@ -5314,7 +5812,7 @@ public: std::vector<TupleClobber> get_clobber_abi () { return clobber_abi; } - std::set<InlineAsmOption> get_options () { return options; } + std::set<InlineAsm::Option> get_options () { return options; } InlineAsm *clone_expr_without_block_impl () const override { @@ -5322,6 +5820,111 @@ public: } Expr::Kind get_expr_kind () const override { return Expr::Kind::InlineAsm; } + + static std::string option_to_string (Option option) + { + switch (option) + { + case Option::PURE: + return "pure"; + case Option::NOMEM: + return "nomem"; + case Option::READONLY: + return "readonly"; + case Option::PRESERVES_FLAGS: + return "preserves_flags"; + case Option::NORETURN: + return "noreturn"; + case Option::NOSTACK: + return "nostack"; + case Option::ATT_SYNTAX: + return "att_syntax"; + case Option::RAW: + return "raw"; + case Option::MAY_UNWIND: + return "may_unwind"; + default: + rust_unreachable (); + } + } +}; + +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; } + const std::vector<TupleTemplateStr> &get_templates () const + { + 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; } + const std::vector<LlvmOperand> &get_inputs () const { return inputs; } + std::vector<LlvmOperand> &get_outputs () { return outputs; } + const std::vector<LlvmOperand> &get_outputs () const { return outputs; } + + std::vector<TupleClobber> &get_clobbers () { return clobbers; } + const std::vector<TupleClobber> &get_clobbers () const { return clobbers; } }; } // namespace AST |
