From: Arthur Cohen <arthur.co...@embecosm.com>

gcc/rust/ChangeLog:

        * ast/rust-ast.h: Add OffsetOf expression kind.
        * ast/rust-builtin-ast-nodes.h (class OffsetOf): Add node.
        * ast/rust-ast.cc: Define it.
        * ast/rust-ast-collector.cc: Add visitor for OffsetOf.
        * ast/rust-ast-collector.h: Likewise.
        * ast/rust-ast-visitor.cc: Likewise.
        * ast/rust-ast-visitor.h: Likewise.
        * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise.
        * hir/rust-ast-lower-base.h: Likewise.
        * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise.
        * hir/rust-ast-lower-expr.h: Likewise.
        * resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise.
        * resolve/rust-ast-resolve-base.h: Likewise.
        * resolve/rust-early-name-resolver-2.0.cc: Likewise.
        * expand/rust-derive.h:
---
 gcc/rust/ast/rust-ast-collector.cc            | 19 +++++++
 gcc/rust/ast/rust-ast-collector.h             |  1 +
 gcc/rust/ast/rust-ast-visitor.cc              |  7 +++
 gcc/rust/ast/rust-ast-visitor.h               |  2 +
 gcc/rust/ast/rust-ast.cc                      | 30 +++++++++++
 gcc/rust/ast/rust-ast.h                       |  1 +
 gcc/rust/ast/rust-builtin-ast-nodes.h         | 53 +++++++++++++++++++
 gcc/rust/expand/rust-derive.h                 |  1 +
 gcc/rust/hir/rust-ast-lower-base.cc           |  4 ++
 gcc/rust/hir/rust-ast-lower-base.h            |  3 ++
 gcc/rust/hir/rust-ast-lower-expr.cc           |  8 +++
 gcc/rust/hir/rust-ast-lower-expr.h            |  3 +-
 gcc/rust/resolve/rust-ast-resolve-base.cc     |  4 ++
 gcc/rust/resolve/rust-ast-resolve-base.h      |  2 +
 .../resolve/rust-early-name-resolver-2.0.cc   |  2 +-
 15 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index 4fe246d7a3a..f4033ad4aae 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -18,6 +18,7 @@
 
 #include "rust-ast-collector.h"
 #include "rust-ast.h"
+#include "rust-builtin-ast-nodes.h"
 #include "rust-diagnostics.h"
 #include "rust-expr.h"
 #include "rust-item.h"
@@ -2982,5 +2983,23 @@ TokenCollector::visit (AST::FormatArgs &fmt)
                 __FILE__, __LINE__);
 }
 
+void
+TokenCollector::visit (AST::OffsetOf &offset_of)
+{
+  auto loc = offset_of.get_locus ();
+
+  push (Rust::Token::make_identifier (loc, "offset_of"));
+  push (Rust::Token::make (EXCLAM, loc));
+  push (Rust::Token::make (LEFT_PAREN, loc));
+
+  visit (offset_of.get_type ());
+
+  push (Rust::Token::make (COMMA, loc));
+
+  push (Rust::Token::make_identifier (offset_of.get_field ()));
+
+  push (Rust::Token::make (RIGHT_PAREN, loc));
+}
+
 } // namespace AST
 } // namespace Rust
diff --git a/gcc/rust/ast/rust-ast-collector.h 
b/gcc/rust/ast/rust-ast-collector.h
index e8af5878a2c..767d211ddf3 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -403,6 +403,7 @@ public:
   void visit (BareFunctionType &type);
 
   void visit (FormatArgs &fmt);
+  void visit (OffsetOf &offset_of);
 };
 } // namespace AST
 
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 7be2ecc1b48..f752b3a8f15 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -19,6 +19,7 @@
 #include "rust-ast-visitor.h"
 #include "rust-ast-full-decls.h"
 #include "rust-ast.h"
+#include "rust-builtin-ast-nodes.h"
 #include "rust-path.h"
 #include "rust-token.h"
 #include "rust-expr.h"
@@ -1489,6 +1490,12 @@ DefaultASTVisitor::visit (AST::FormatArgs &)
   // FIXME: Do we have anything to do? any subnodes to visit? Probably, right?
 }
 
+void
+DefaultASTVisitor::visit (AST::OffsetOf &offset_of)
+{
+  visit (offset_of.get_type ());
+}
+
 void
 DefaultASTVisitor::visit (AST::VariadicParam &param)
 {
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index 6111b0548ed..020400dde3f 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -238,6 +238,7 @@ public:
 
   // special AST nodes for certain builtin macros such as `asm!()`
   virtual void visit (FormatArgs &fmt) = 0;
+  virtual void visit (OffsetOf &fmt) = 0;
 
   // TODO: rust-cond-compilation.h visiting? not currently used
 };
@@ -408,6 +409,7 @@ public:
   virtual void visit (AST::FunctionParam &param) override;
   virtual void visit (AST::VariadicParam &param) override;
   virtual void visit (AST::FormatArgs &fmt) override;
+  virtual void visit (AST::OffsetOf &fmt) override;
 
   template <typename T> void visit (T &node) { node.accept_vis (*this); }
 
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 2b7ee5cb8bf..ec1596bfb97 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -5088,6 +5088,12 @@ FormatArgs::accept_vis (ASTVisitor &vis)
   vis.visit (*this);
 }
 
+void
+OffsetOf::accept_vis (ASTVisitor &vis)
+{
+  vis.visit (*this);
+}
+
 std::string
 FormatArgs::as_string () const
 {
@@ -5095,6 +5101,12 @@ FormatArgs::as_string () const
   return "FormatArgs";
 }
 
+std::string
+OffsetOf::as_string () const
+{
+  return "OffsetOf(" + type->as_string () + ", " + field.as_string () + ")";
+}
+
 location_t
 FormatArgs::get_locus () const
 {
@@ -5139,6 +5151,24 @@ FormatArgs::clone_expr_impl () const
   return new FormatArgs (*this);
 }
 
+std::vector<Attribute> &
+OffsetOf::get_outer_attrs ()
+{
+  rust_unreachable ();
+}
+
+void
+OffsetOf::set_outer_attrs (std::vector<Attribute>)
+{
+  rust_unreachable ();
+}
+
+Expr *
+OffsetOf::clone_expr_impl () const
+{
+  return new OffsetOf (*this);
+}
+
 } // namespace AST
 
 std::ostream &
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 33c50b71d38..93d4ff132e5 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1307,6 +1307,7 @@ public:
     LlvmInlineAsm,
     Identifier,
     FormatArgs,
+    OffsetOf,
     MacroInvocation,
     Borrow,
     Dereference,
diff --git a/gcc/rust/ast/rust-builtin-ast-nodes.h 
b/gcc/rust/ast/rust-builtin-ast-nodes.h
index 3684092aca2..2893e7b4676 100644
--- a/gcc/rust/ast/rust-builtin-ast-nodes.h
+++ b/gcc/rust/ast/rust-builtin-ast-nodes.h
@@ -225,6 +225,59 @@ protected:
   virtual Expr *clone_expr_impl () const override;
 };
 
+/**
+ * The node associated with the builtin offset_of!() macro
+ */
+class OffsetOf : public Expr
+{
+public:
+  OffsetOf (std::unique_ptr<Type> &&type, Identifier field, location_t loc)
+    : type (std::move (type)), field (field), loc (loc)
+  {}
+
+  OffsetOf (const OffsetOf &other)
+    : type (other.type->clone_type ()), field (other.field), loc (other.loc),
+      marked_for_strip (other.marked_for_strip)
+  {}
+
+  OffsetOf &operator= (const OffsetOf &other)
+  {
+    type = other.type->clone_type ();
+    field = other.field;
+    loc = other.loc;
+    marked_for_strip = other.marked_for_strip;
+
+    return *this;
+  }
+
+  void accept_vis (AST::ASTVisitor &vis) override;
+
+  virtual location_t get_locus () const override { return loc; }
+  const Type &get_type () const { return *type; }
+  Type &get_type () { return *type; }
+  const Identifier &get_field () const { return field; }
+
+  bool is_expr_without_block () const override { return false; }
+
+  void mark_for_strip () override { marked_for_strip = true; }
+  bool is_marked_for_strip () const override { return marked_for_strip; }
+
+  std::string as_string () const override;
+
+  std::vector<Attribute> &get_outer_attrs () override;
+  void set_outer_attrs (std::vector<Attribute>) override;
+  Expr *clone_expr_impl () const override;
+
+  Expr::Kind get_expr_kind () const override { return Expr::Kind::OffsetOf; }
+
+private:
+  std::unique_ptr<Type> type;
+  Identifier field;
+
+  location_t loc;
+  bool marked_for_strip = false;
+};
+
 } // namespace AST
 } // namespace Rust
 
diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h
index 61c7355e7ab..297d0799122 100644
--- a/gcc/rust/expand/rust-derive.h
+++ b/gcc/rust/expand/rust-derive.h
@@ -254,6 +254,7 @@ private:
   virtual void visit (FunctionParam &param) override final{};
   virtual void visit (VariadicParam &param) override final{};
   virtual void visit (FormatArgs &param) override final{};
+  virtual void visit (OffsetOf &param) override final{};
 };
 
 } // namespace AST
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc 
b/gcc/rust/hir/rust-ast-lower-base.cc
index b07ac0c0750..8e8f3b649d0 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -560,6 +560,10 @@ void
 ASTLoweringBase::visit (AST::FormatArgs &fmt)
 {}
 
+void
+ASTLoweringBase::visit (AST::OffsetOf &offset_of)
+{}
+
 HIR::Lifetime
 ASTLoweringBase::lower_lifetime (AST::Lifetime &lifetime,
                                 bool default_to_static_lifetime)
diff --git a/gcc/rust/hir/rust-ast-lower-base.h 
b/gcc/rust/hir/rust-ast-lower-base.h
index 0284ff0c82b..d9428d61be9 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -20,6 +20,8 @@
 #define RUST_AST_LOWER_BASE
 
 #include "rust-ast.h"
+#include "rust-builtin-ast-nodes.h"
+#include "rust-expr.h"
 #include "rust-system.h"
 #include "rust-ast-full.h"
 #include "rust-ast-visitor.h"
@@ -262,6 +264,7 @@ public:
   virtual void visit (AST::SelfParam &param) override;
 
   virtual void visit (AST::FormatArgs &fmt) override;
+  virtual void visit (AST::OffsetOf &offset_of) override;
 
 protected:
   ASTLoweringBase ()
diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc 
b/gcc/rust/hir/rust-ast-lower-expr.cc
index 96820fd8c18..31126a8ad35 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.cc
+++ b/gcc/rust/hir/rust-ast-lower-expr.cc
@@ -24,6 +24,7 @@
 #include "rust-ast-lower-pattern.h"
 #include "rust-ast-lower-type.h"
 #include "rust-ast.h"
+#include "rust-builtin-ast-nodes.h"
 #include "rust-diagnostics.h"
 #include "rust-hir-map.h"
 #include "rust-system.h"
@@ -1055,5 +1056,12 @@ ASTLoweringExpr::visit (AST::FormatArgs &fmt)
                 "FormatArgs lowering is not implemented yet");
 }
 
+void
+ASTLoweringExpr::visit (AST::OffsetOf &offset_of)
+{
+  // FIXME: Implement HIR::OffsetOf node and const evaluation
+  rust_unreachable ();
+}
+
 } // namespace HIR
 } // namespace Rust
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h 
b/gcc/rust/hir/rust-ast-lower-expr.h
index 9d1bf68e876..eb822c9f4de 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -126,8 +126,9 @@ public:
   void visit (AST::InlineAsm &expr) override;
   void visit (AST::LlvmInlineAsm &expr) override;
 
-  // Extra visitor for FormatArgs nodes
+  // Extra visitor for builtin macro nodes
   void visit (AST::FormatArgs &fmt) override;
+  void visit (AST::OffsetOf &offset_of) override;
 
 private:
   ASTLoweringExpr ();
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc 
b/gcc/rust/resolve/rust-ast-resolve-base.cc
index 05f34bc3f87..4890d8e519c 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-base.cc
@@ -675,5 +675,9 @@ void
 ResolverBase::visit (AST::FormatArgs &fmt)
 {}
 
+void
+ResolverBase::visit (AST::OffsetOf &offset_of)
+{}
+
 } // namespace Resolver
 } // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h 
b/gcc/rust/resolve/rust-ast-resolve-base.h
index 0cbf78e39ab..dce8e7bfc75 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.h
+++ b/gcc/rust/resolve/rust-ast-resolve-base.h
@@ -21,6 +21,7 @@
 
 #include "rust-ast-visitor.h"
 #include "rust-ast.h"
+#include "rust-builtin-ast-nodes.h"
 #include "rust-expr.h"
 #include "rust-name-resolver.h"
 #include "rust-diagnostics.h"
@@ -211,6 +212,7 @@ public:
   void visit (AST::SelfParam &param);
 
   void visit (AST::FormatArgs &fmt);
+  void visit (AST::OffsetOf &offset_of);
 
 protected:
   ResolverBase ()
diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index fa746d770fb..bb93d95fe8e 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -18,7 +18,7 @@
 
 #include "rust-early-name-resolver-2.0.h"
 #include "optional.h"
-#include "rust-ast-full.h"
+#include "options.h"
 #include "rust-diagnostics.h"
 #include "rust-hir-map.h"
 #include "rust-item.h"
-- 
2.49.0

Reply via email to