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.h196
1 files changed, 144 insertions, 52 deletions
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 9477bf0..438d3d3 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4768,9 +4768,10 @@ struct InlineAsmRegOrRegClass
location_t locus;
};
-struct InlineAsmOperand
+class InlineAsmOperand
{
- enum RegisterType
+public:
+ enum class RegisterType
{
In,
Out,
@@ -4781,8 +4782,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;
@@ -4807,10 +4824,14 @@ struct InlineAsmOperand
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
@@ -4836,10 +4857,14 @@ struct InlineAsmOperand
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
@@ -4866,10 +4891,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;
@@ -4901,15 +4930,23 @@ 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))
@@ -4926,10 +4963,14 @@ struct InlineAsmOperand
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;
@@ -4950,76 +4991,127 @@ struct InlineAsmOperand
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 ()
+ {
+ rust_assert (register_type == RegisterType::InOut);
+ return static_cast<InOut &> (*reg);
+ }
+ const InOut &get_in_out () const
{
- this->register_type = InOut;
- if (reg.has_value ())
- this->in_out = reg.value ();
+ 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