From: badumbatish <tanghocle...@gmail.com>

gcc/rust/ChangeLog:

        * hir/rust-ast-lower-expr.cc (from_operand):
        Set up the lowering for operand
        (ASTLoweringExpr::visit): Likewise
        * hir/tree/rust-hir-expr.h (struct InlineAsmRegOrRegClass):
        Not necessary, kept from ast
        (struct AnonConst): Set up lowering for operand
        (class InlineAsmOperand): Likewise, add getters
---
 gcc/rust/hir/rust-ast-lower-expr.cc | 100 ++++++++++-
 gcc/rust/hir/tree/rust-hir-expr.h   | 257 ++++++++++++++++++++++++++--
 2 files changed, 343 insertions(+), 14 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc 
b/gcc/rust/hir/rust-ast-lower-expr.cc
index be7ff413c93..45277e87714 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.cc
+++ b/gcc/rust/hir/rust-ast-lower-expr.cc
@@ -829,6 +829,92 @@ ASTLoweringExpr::visit (AST::ClosureExprInnerTyped &expr)
                            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)
 {
@@ -837,10 +923,22 @@ 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
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h 
b/gcc/rust/hir/tree/rust-hir-expr.h
index ff9fcee1a46..5d2cdd1814a 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -3843,28 +3843,259 @@ class InlineAsmRegClass
   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> &reg,
+       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> &reg, 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> &reg, 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> &reg,
+               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 &reg)
+    : register_type (RegisterType::In), in (reg)
+  {}
+
+  InlineAsmOperand (const struct Out &reg)
+    : register_type (RegisterType::Out), out (reg)
+  {}
+  InlineAsmOperand (const struct InOut &reg)
+    : register_type (RegisterType::InOut), in_out (reg)
+  {}
+  InlineAsmOperand (const struct SplitInOut &reg)
+    : register_type (RegisterType::SplitInOut), split_in_out (reg)
+  {}
+  InlineAsmOperand (const struct Const &reg)
+    : register_type (RegisterType::Const), cnst (reg)
+  {}
+  InlineAsmOperand (const struct Sym &reg)
+    : register_type (RegisterType::Sym), sym (reg)
+  {}
+  InlineAsmOperand (const struct Label &reg)
+    : 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
 {
@@ -3876,7 +4107,7 @@ public:
 
   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;
 
@@ -3909,7 +4140,7 @@ public:
     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; }
 
@@ -3918,7 +4149,7 @@ public:
   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,
-- 
2.45.2

Reply via email to