aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/ast/rust-expr.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/ast/rust-expr.h')
-rw-r--r--gcc/rust/ast/rust-expr.h500
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> &reg)
- {
- this->register_type = In;
+ InlineAsmOperand (const In &reg, location_t locus)
+ : register_type (RegisterType::In), locus (locus), reg (new In (reg))
+ {}
+ InlineAsmOperand (const Out &reg, location_t locus)
+ : register_type (RegisterType::Out), locus (locus), reg (new Out (reg))
+ {}
+ InlineAsmOperand (const InOut &reg, location_t locus)
+ : register_type (RegisterType::InOut), locus (locus), reg (new InOut (reg))
+ {}
+ InlineAsmOperand (const SplitInOut &reg, location_t locus)
+ : register_type (RegisterType::SplitInOut), locus (locus),
+ reg (new SplitInOut (reg))
+ {}
+ InlineAsmOperand (const Const &reg, location_t locus)
+ : register_type (RegisterType::Const), locus (locus), reg (new Const (reg))
+ {}
+ InlineAsmOperand (const Sym &reg, location_t locus)
+ : register_type (RegisterType::Sym), locus (locus), reg (new Sym (reg))
+ {}
+ InlineAsmOperand (const Label &reg, 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> &reg)
+ // 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> &reg)
+ 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> &reg)
+ 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> &reg)
+ 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> &reg)
+ 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> &reg)
+ 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