expr.get_locus ());
}
+HIR::InlineAsmOperand
+from_operand (const AST::InlineAsmOperand &operand)
+{
+ using RegisterType = AST::InlineAsmOperand::RegisterType;
+ using Operand = HIR::InlineAsmOperand;
+ auto type = operand.get_register_type ();
+
+ /*In,*/
+ /*Out,*/
+ /*InOut,*/
+ /*SplitInOut,*/
+ /*Const,*/
+ /*Sym,*/
+ /*Label,*/
+ if (type == RegisterType::In)
+ {
+ auto in_value = operand.get_in ();
+
+ struct Operand::In in (in_value.reg,
+ std::unique_ptr<Expr> (ASTLoweringExpr::translate (
+ *in_value.expr.get ())));
+ return in;
+ }
+ else if (type == RegisterType::Out)
+ {
+ auto out_value = operand.get_out ();
+ struct Operand::Out out (out_value.reg, out_value.late,
+ std::unique_ptr<Expr> (
+ ASTLoweringExpr::translate (
+ *out_value.expr.get ())));
+ return out;
+ }
+ else if (type == RegisterType::InOut)
+ {
+ auto inout_value = operand.get_in_out ();
+ struct Operand::InOut inout (inout_value.reg, inout_value.late,
+ std::unique_ptr<Expr> (
+ ASTLoweringExpr::translate (
+ *inout_value.expr.get ())));
+ return inout;
+ }
+ else if (type == RegisterType::SplitInOut)
+ {
+ auto split_in_out_value = operand.get_split_in_out ();
+ struct Operand::SplitInOut split_in_out (
+ split_in_out_value.reg, split_in_out_value.late,
+ std::unique_ptr<Expr> (
+ ASTLoweringExpr::translate (*split_in_out_value.in_expr.get ())),
+ std::unique_ptr<Expr> (
+ ASTLoweringExpr::translate (*split_in_out_value.out_expr.get ())));
+ return split_in_out;
+ }
+ else if (type == RegisterType::Const)
+ {
+ auto const_value = operand.get_const ();
+ struct HIR::AnonConst anon_const (
+ const_value.anon_const.id,
+ std::unique_ptr<Expr> (
+ ASTLoweringExpr::translate (*const_value.anon_const.expr.get ())));
+ struct Operand::Const cnst
+ {
+ anon_const
+ };
+ return cnst;
+ }
+ else if (type == RegisterType::Sym)
+ {
+ auto sym_value = operand.get_sym ();
+ struct Operand::Sym sym (std::unique_ptr<Expr> (
+ ASTLoweringExpr::translate (*sym_value.expr.get ())));
+ return sym;
+ }
+ else if (type == RegisterType::Label)
+ {
+ auto label_value = operand.get_label ();
+ struct Operand::Label label (label_value.label_name,
+ std::unique_ptr<Expr> (
+ ASTLoweringExpr::translate (
+ *label_value.expr.get ())));
+ return label;
+ }
+ else
+ {
+ rust_unreachable ();
+ }
+}
void
ASTLoweringExpr::visit (AST::InlineAsm &expr)
{
mappings.get_next_hir_id (crate_num),
mappings.get_next_localdef_id (crate_num));
+ std::vector<HIR::InlineAsmOperand> hir_operands;
+ std::vector<AST::InlineAsmOperand> ast_operands = expr.get_operands ();
+ /*int ast_operands_size = ast_operands.size ();*/
+ for (auto &operand : ast_operands)
+ {
+ hir_operands.push_back (from_operand (operand));
+ }
+ /*int hir_operands_size = hir_operands.size ();*/
+
+ /*rust_debug ("{bdbt} : There are %d ast operands prelowering and %d hir "*/
+ /* "operands after lowering\n",*/
+ /* ast_operands_size, hir_operands_size);*/
translated
= new HIR::InlineAsm (expr.get_locus (), expr.is_global_asm,
expr.get_template_ (), expr.get_template_strs (),
- expr.get_operands (), expr.get_clobber_abi (),
+ hir_operands, expr.get_clobber_abi (),
expr.get_options (), mapping);
}
void
std::string placeholder;
};
-struct InlineAsmRegOrRegClass
+struct AnonConst
{
- enum Type
+ 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;
+ }
+};
+;
+
+class InlineAsmOperand
+{
+public:
+ struct In
{
- Reg, // links to struct Register
- RegClass, // links to struct RegisterClass
+ tl::optional<struct AST::InlineAsmRegOrRegClass> reg;
+ std::unique_ptr<Expr> expr;
+
+ In (const tl::optional<struct AST::InlineAsmRegOrRegClass> ®,
+ std::unique_ptr<Expr> expr)
+ : reg (reg), expr (std::move (expr))
+ {
+ rust_assert (this->expr != nullptr);
+ }
+
+ In (const struct In &other)
+ {
+ reg = other.reg;
+
+ expr = other.expr->clone_expr ();
+ }
+
+ In operator= (const struct In &other)
+ {
+ reg = other.reg;
+ expr = other.expr->clone_expr ();
+
+ return *this;
+ }
};
- struct Register
+ struct Out
{
- InlineAsmReg Reg;
+ tl::optional<struct AST::InlineAsmRegOrRegClass> reg;
+ bool late;
+ std::unique_ptr<Expr> expr; // can be null
+
+ Out (tl::optional<struct AST::InlineAsmRegOrRegClass> ®, bool late,
+ std::unique_ptr<Expr> expr)
+ : reg (reg), late (late), expr (std::move (expr))
+ {
+ rust_assert (this->expr != nullptr);
+ }
+
+ Out (const struct Out &other)
+ {
+ reg = other.reg;
+ late = other.late;
+ expr = other.expr->clone_expr ();
+ }
+
+ Out operator= (const struct Out &other)
+ {
+ reg = other.reg;
+ late = other.late;
+ expr = other.expr->clone_expr ();
+ return *this;
+ }
};
- struct RegisterClass
+ struct InOut
{
- InlineAsmRegClass RegClass;
+ tl::optional<struct AST::InlineAsmRegOrRegClass> reg;
+ bool late;
+ std::unique_ptr<Expr> expr; // this can't be null
+
+ InOut (tl::optional<struct AST::InlineAsmRegOrRegClass> ®, bool late,
+ std::unique_ptr<Expr> expr)
+ : reg (reg), late (late), expr (std::move (expr))
+ {
+ rust_assert (this->expr != nullptr);
+ }
+
+ InOut (const struct InOut &other)
+ {
+ reg = other.reg;
+ late = other.late;
+ expr = other.expr->clone_expr ();
+ }
+
+ InOut operator= (const struct InOut &other)
+ {
+ reg = other.reg;
+ late = other.late;
+ expr = other.expr->clone_expr ();
+
+ return *this;
+ }
+ };
+
+ struct SplitInOut
+ {
+ tl::optional<struct AST::InlineAsmRegOrRegClass> reg;
+ bool late;
+ std::unique_ptr<Expr> in_expr;
+ std::unique_ptr<Expr> out_expr; // could be null
+
+ SplitInOut (tl::optional<struct AST::InlineAsmRegOrRegClass> ®,
+ bool late, std::unique_ptr<Expr> in_expr,
+ std::unique_ptr<Expr> out_expr)
+ : reg (reg), late (late), in_expr (std::move (in_expr)),
+ out_expr (std::move (out_expr))
+ {
+ rust_assert (this->in_expr != nullptr);
+ rust_assert (this->out_expr != nullptr);
+ }
+
+ SplitInOut (const struct SplitInOut &other)
+ {
+ reg = other.reg;
+ late = other.late;
+ in_expr = other.in_expr->clone_expr ();
+ out_expr = other.out_expr->clone_expr ();
+ }
+
+ SplitInOut operator= (const struct SplitInOut &other)
+ {
+ reg = other.reg;
+ late = other.late;
+ in_expr = other.in_expr->clone_expr ();
+ out_expr = other.out_expr->clone_expr ();
+
+ return *this;
+ }
+ };
+
+ struct Const
+ {
+ AnonConst anon_const;
};
- Identifier name;
+ struct Sym
+ {
+ 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)
+ {
+ expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
+ }
+
+ Sym operator= (const struct Sym &other)
+ {
+ expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
+ return *this;
+ }
+ };
+
+ struct Label
+ {
+ std::string label_name;
+ std::unique_ptr<Expr> expr;
+
+ Label (tl::optional<std::string> label_name, std::unique_ptr<Expr> expr)
+ : expr (std::move (expr))
+ {
+ rust_assert (this->expr != nullptr);
+ if (label_name.has_value ())
+ this->label_name = label_name.value ();
+ }
+ Label (const struct Label &other)
+ {
+ expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
+ }
+
+ Label operator= (const struct Label &other)
+ {
+ expr = std::unique_ptr<Expr> (other.expr->clone_expr ());
+ return *this;
+ }
+ };
+
+private:
+ using RegisterType = AST::InlineAsmOperand::RegisterType;
+ AST::InlineAsmOperand::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;
location_t locus;
-};
+public:
+ InlineAsmOperand (const InlineAsmOperand &other)
+ : register_type (other.register_type), in (other.in), out (other.out),
+ in_out (other.in_out), split_in_out (other.split_in_out),
+ cnst (other.cnst), sym (other.sym)
+ {}
+
+ InlineAsmOperand (const struct In ®)
+ : register_type (RegisterType::In), in (reg)
+ {}
+
+ InlineAsmOperand (const struct Out ®)
+ : register_type (RegisterType::Out), out (reg)
+ {}
+ InlineAsmOperand (const struct InOut ®)
+ : register_type (RegisterType::InOut), in_out (reg)
+ {}
+ InlineAsmOperand (const struct SplitInOut ®)
+ : register_type (RegisterType::SplitInOut), split_in_out (reg)
+ {}
+ InlineAsmOperand (const struct Const ®)
+ : register_type (RegisterType::Const), cnst (reg)
+ {}
+ InlineAsmOperand (const struct Sym ®)
+ : register_type (RegisterType::Sym), sym (reg)
+ {}
+ InlineAsmOperand (const struct Label ®)
+ : register_type (RegisterType::Label), label (reg)
+ {}
+
+ RegisterType get_register_type () const { return register_type; }
+
+ // Potentially unsafe without get_register_type() check
+ struct In get_in () const { return in.value (); }
+ struct Out get_out () const { return out.value (); }
+ struct InOut get_in_out () const { return in_out.value (); }
+ struct SplitInOut get_split_in_out () const { return split_in_out.value (); }
+ struct Const get_const () const { return cnst.value (); }
+ struct Sym get_sym () const { return sym.value (); }
+ struct Label get_label () const { return label.value (); }
+};
// Inline Assembly Node
class InlineAsm : public ExprWithoutBlock
{
std::vector<AST::InlineAsmTemplatePiece> template_;
std::vector<AST::TupleTemplateStr> template_strs;
- std::vector<AST::InlineAsmOperand> operands;
+ std::vector<HIR::InlineAsmOperand> operands;
std::vector<AST::TupleClobber> clobber_abi;
std::set<AST::InlineAsmOption> options;
return template_strs;
}
- std::vector<AST::InlineAsmOperand> get_operands () { return operands; }
+ std::vector<HIR::InlineAsmOperand> get_operands () { return operands; }
std::vector<AST::TupleClobber> get_clobber_abi () { return clobber_abi; }
InlineAsm (location_t locus, bool is_global_asm,
std::vector<AST::InlineAsmTemplatePiece> template_,
std::vector<AST::TupleTemplateStr> template_strs,
- std::vector<AST::InlineAsmOperand> operands,
+ std::vector<HIR::InlineAsmOperand> operands,
std::vector<AST::TupleClobber> clobber_abi,
std::set<AST::InlineAsmOption> options,
Analysis::NodeMapping mappings,