From: Arthur Cohen <arthur.co...@embecosm.com> gcc/rust/ChangeLog:
* hir/tree/rust-hir-expr.h (class OffsetOf): New. * hir/tree/rust-hir-expr.cc: Define its methods. * hir/tree/rust-hir-expr-abstract.h: Add ExprType::OffsetOf. * hir/tree/rust-hir-full-decls.h (class OffsetOf): Declare it. * backend/rust-compile-block.h: Add handling for OffsetOf. * backend/rust-compile-expr.cc (CompileExpr::visit): Likewise. * backend/rust-compile-expr.h: Likewise. * checks/errors/borrowck/rust-bir-builder-expr-stmt.cc (ExprStmtBuilder::visit): Likewise. * checks/errors/borrowck/rust-bir-builder-expr-stmt.h (RUST_BIR_BUILDER_EXPR_H): Likewise. * checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h: Likewise. * checks/errors/borrowck/rust-bir-builder-struct.h: Likewise. * checks/errors/borrowck/rust-function-collector.h: Likewise. * checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::visit): Likewise. * checks/errors/privacy/rust-privacy-reporter.h (RUST_PRIVACY_REPORTER_H): Likewise. * checks/errors/rust-const-checker.cc (ConstChecker::visit): Likewise. * checks/errors/rust-const-checker.h: Likewise. * checks/errors/rust-hir-pattern-analysis.cc (PatternChecker::visit): Likewise. * checks/errors/rust-hir-pattern-analysis.h: Likewise. * checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): Likewise. * checks/errors/rust-unsafe-checker.h: Likewise. * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise. * hir/rust-hir-dump.cc (Dump::visit): Likewise. * hir/rust-hir-dump.h: Likewise. * hir/tree/rust-hir-visitor.cc (DefaultHIRVisitor::walk): Likewise. * hir/tree/rust-hir-visitor.h: Likewise. * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Likewise. * typecheck/rust-hir-type-check-expr.h (RUST_HIR_TYPE_CHECK_EXPR): Likewise. gcc/testsuite/ChangeLog: * rust/compile/offset_of2.rs: New test. --- gcc/rust/backend/rust-compile-block.h | 3 ++ gcc/rust/backend/rust-compile-expr.cc | 6 ++++ gcc/rust/backend/rust-compile-expr.h | 1 + .../borrowck/rust-bir-builder-expr-stmt.cc | 4 +++ .../borrowck/rust-bir-builder-expr-stmt.h | 2 ++ .../borrowck/rust-bir-builder-lazyboolexpr.h | 1 + .../errors/borrowck/rust-bir-builder-struct.h | 2 ++ .../errors/borrowck/rust-function-collector.h | 2 ++ .../errors/privacy/rust-privacy-reporter.cc | 6 ++++ .../errors/privacy/rust-privacy-reporter.h | 2 ++ gcc/rust/checks/errors/rust-const-checker.cc | 4 +++ gcc/rust/checks/errors/rust-const-checker.h | 1 + .../errors/rust-hir-pattern-analysis.cc | 4 +++ .../checks/errors/rust-hir-pattern-analysis.h | 1 + gcc/rust/checks/errors/rust-unsafe-checker.cc | 6 ++++ gcc/rust/checks/errors/rust-unsafe-checker.h | 1 + gcc/rust/hir/rust-ast-lower-expr.cc | 12 +++++-- gcc/rust/hir/rust-hir-dump.cc | 11 ++++++ gcc/rust/hir/rust-hir-dump.h | 1 + gcc/rust/hir/tree/rust-hir-expr-abstract.h | 1 + gcc/rust/hir/tree/rust-hir-expr.cc | 36 +++++++++++++++++++ gcc/rust/hir/tree/rust-hir-expr.h | 36 +++++++++++++++++++ gcc/rust/hir/tree/rust-hir-full-decls.h | 1 + gcc/rust/hir/tree/rust-hir-visitor.cc | 6 ++++ gcc/rust/hir/tree/rust-hir-visitor.h | 5 +++ .../typecheck/rust-hir-type-check-expr.cc | 13 +++++++ gcc/rust/typecheck/rust-hir-type-check-expr.h | 2 ++ gcc/testsuite/rust/compile/offset_of2.rs | 9 +++++ 28 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/rust/compile/offset_of2.rs diff --git a/gcc/rust/backend/rust-compile-block.h b/gcc/rust/backend/rust-compile-block.h index 90515f64883..f84bace15af 100644 --- a/gcc/rust/backend/rust-compile-block.h +++ b/gcc/rust/backend/rust-compile-block.h @@ -20,6 +20,7 @@ #define RUST_COMPILE_BLOCK #include "rust-compile-base.h" +#include "rust-hir-expr.h" #include "rust-hir-visitor.h" namespace Rust { @@ -103,6 +104,7 @@ public: void visit (HIR::AsyncBlockExpr &) override {} void visit (HIR::InlineAsm &) override {} void visit (HIR::LlvmInlineAsm &) override {} + void visit (HIR::OffsetOf &) override {} private: CompileConditionalBlocks (Context *ctx, Bvariable *result) @@ -192,6 +194,7 @@ public: void visit (HIR::AsyncBlockExpr &) override {} void visit (HIR::InlineAsm &) override {} void visit (HIR::LlvmInlineAsm &) override {} + void visit (HIR::OffsetOf &) override {} void visit (HIR::AnonConst &) override {} private: diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 25da59d982d..547bb7c27a8 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -375,6 +375,12 @@ CompileExpr::visit (HIR::LlvmInlineAsm &expr) ctx->add_statement (asm_codegen.tree_codegen_asm (expr)); } +void +CompileExpr::visit (HIR::OffsetOf &expr) +{ + rust_unreachable (); +} + void CompileExpr::visit (HIR::IfExprConseqElse &expr) { diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index bc347bf5066..b8b4e8dfdd5 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -72,6 +72,7 @@ public: void visit (HIR::ClosureExpr &expr) override; void visit (HIR::InlineAsm &expr) override; void visit (HIR::LlvmInlineAsm &expr) override; + void visit (HIR::OffsetOf &expr) override; // TODO void visit (HIR::ErrorPropagationExpr &) override {} diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc index 0799a4ea84c..5b22c1a68a3 100644 --- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc +++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc @@ -330,6 +330,10 @@ void ExprStmtBuilder::visit (HIR::LlvmInlineAsm &expr) {} +void +ExprStmtBuilder::visit (HIR::OffsetOf &expr) +{} + void ExprStmtBuilder::visit (HIR::MethodCallExpr &expr) {} diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h index 45d3d584825..ba5db8b0c3e 100644 --- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h +++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h @@ -19,6 +19,7 @@ #ifndef RUST_BIR_BUILDER_EXPR_H #define RUST_BIR_BUILDER_EXPR_H +#include "rust-hir-expr.h" #include "rust-hir-visitor.h" #include "rust-bir-builder-internal.h" @@ -103,6 +104,7 @@ protected: // Expr void visit (HIR::IfExprConseqElse &expr) override; void visit (HIR::InlineAsm &expr) override; void visit (HIR::LlvmInlineAsm &expr) override; + void visit (HIR::OffsetOf &expr) override; void visit (HIR::MatchExpr &expr) override; void visit (HIR::AwaitExpr &expr) override; diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h index a5ec5690743..9108009de10 100644 --- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h +++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h @@ -216,6 +216,7 @@ public: void visit (HIR::InlineAsm &expr) override {} void visit (HIR::LlvmInlineAsm &expr) override {} + void visit (HIR::OffsetOf &expr) override {} protected: // Illegal at this position. void visit (HIR::StructExprFieldIdentifier &field) override diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h index 2e11f635110..d87ff8cb33c 100644 --- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h +++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h @@ -21,6 +21,7 @@ #include "rust-bir-builder-internal.h" #include "rust-bir-builder-expr-stmt.h" +#include "rust-hir-expr.h" namespace Rust { namespace BIR { @@ -156,6 +157,7 @@ protected: void visit (HIR::AsyncBlockExpr &expr) override { rust_unreachable (); } void visit (HIR::InlineAsm &expr) override { rust_unreachable (); } void visit (HIR::LlvmInlineAsm &expr) override { rust_unreachable (); } + void visit (HIR::OffsetOf &expr) override { rust_unreachable (); } void visit (HIR::TypeParam ¶m) override { rust_unreachable (); } void visit (HIR::ConstGenericParam ¶m) override { rust_unreachable (); } void visit (HIR::LifetimeWhereClauseItem &item) override diff --git a/gcc/rust/checks/errors/borrowck/rust-function-collector.h b/gcc/rust/checks/errors/borrowck/rust-function-collector.h index 860915e0920..86f96c14d62 100644 --- a/gcc/rust/checks/errors/borrowck/rust-function-collector.h +++ b/gcc/rust/checks/errors/borrowck/rust-function-collector.h @@ -19,6 +19,7 @@ #ifndef RUST_HIR_FUNCTION_COLLECTOR_H #define RUST_HIR_FUNCTION_COLLECTOR_H +#include "rust-hir-expr.h" #include "rust-hir-item.h" #include "rust-hir-visitor.h" #include "rust-hir.h" @@ -126,6 +127,7 @@ public: void visit (HIR::AsyncBlockExpr &expr) override {} void visit (HIR::InlineAsm &expr) override {} void visit (HIR::LlvmInlineAsm &expr) override {} + void visit (HIR::OffsetOf &expr) override {} void visit (HIR::TypeParam ¶m) override {} void visit (HIR::ConstGenericParam ¶m) override {} void visit (HIR::LifetimeWhereClauseItem &item) override {} diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc index e8a679214d4..af529931b26 100644 --- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc +++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc @@ -313,6 +313,12 @@ void PrivacyReporter::visit (HIR::LlvmInlineAsm &) {} +void +PrivacyReporter::visit (HIR::OffsetOf &expr) +{ + // TODO: Do we have to do anything? +} + void PrivacyReporter::visit (HIR::TypePath &path) { diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h index 07eebf65df0..72716a6aa8a 100644 --- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h +++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h @@ -19,6 +19,7 @@ #ifndef RUST_PRIVACY_REPORTER_H #define RUST_PRIVACY_REPORTER_H +#include "rust-hir-expr.h" #include "rust-hir-map.h" #include "rust-hir-visitor.h" #include "rust-mapping-common.h" @@ -128,6 +129,7 @@ types virtual void visit (HIR::AsyncBlockExpr &expr); virtual void visit (HIR::InlineAsm &expr); virtual void visit (HIR::LlvmInlineAsm &expr); + virtual void visit (HIR::OffsetOf &expr); virtual void visit (HIR::EnumItemTuple &); virtual void visit (HIR::EnumItemStruct &); diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc index 5cbab3d554c..c40f9db7d2c 100644 --- a/gcc/rust/checks/errors/rust-const-checker.cc +++ b/gcc/rust/checks/errors/rust-const-checker.cc @@ -560,6 +560,10 @@ void ConstChecker::visit (LlvmInlineAsm &) {} +void +ConstChecker::visit (OffsetOf &) +{} + void ConstChecker::visit (TypeParam &) {} diff --git a/gcc/rust/checks/errors/rust-const-checker.h b/gcc/rust/checks/errors/rust-const-checker.h index 22398747e58..eb63095a225 100644 --- a/gcc/rust/checks/errors/rust-const-checker.h +++ b/gcc/rust/checks/errors/rust-const-checker.h @@ -135,6 +135,7 @@ private: virtual void visit (AsyncBlockExpr &expr) override; virtual void visit (InlineAsm &expr) override; virtual void visit (LlvmInlineAsm &expr) override; + virtual void visit (OffsetOf &expr) override; virtual void visit (TypeParam ¶m) override; virtual void visit (ConstGenericParam ¶m) override; diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc index ec22a0ee92e..25669713a00 100644 --- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc +++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc @@ -438,6 +438,10 @@ void PatternChecker::visit (LlvmInlineAsm &expr) {} +void +PatternChecker::visit (OffsetOf &expr) +{} + void PatternChecker::visit (TypeParam &) {} diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h index 5766180ec79..dd44abca527 100644 --- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h +++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h @@ -109,6 +109,7 @@ private: virtual void visit (AsyncBlockExpr &expr) override; virtual void visit (InlineAsm &expr) override; virtual void visit (LlvmInlineAsm &expr) override; + virtual void visit (OffsetOf &expr) override; virtual void visit (TypeParam ¶m) override; virtual void visit (ConstGenericParam ¶m) override; virtual void visit (LifetimeWhereClauseItem &item) override; diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc index d90088faf74..405c59be096 100644 --- a/gcc/rust/checks/errors/rust-unsafe-checker.cc +++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc @@ -693,6 +693,12 @@ UnsafeChecker::visit (LlvmInlineAsm &expr) "use of inline assembly is unsafe and requires unsafe function or block"); } +void +UnsafeChecker::visit (OffsetOf &expr) +{ + // nothing to do, offset_of!() is safe +} + void UnsafeChecker::visit (TypeParam &) {} diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.h b/gcc/rust/checks/errors/rust-unsafe-checker.h index 8a9830f7cd6..dc3b482f15b 100644 --- a/gcc/rust/checks/errors/rust-unsafe-checker.h +++ b/gcc/rust/checks/errors/rust-unsafe-checker.h @@ -117,6 +117,7 @@ private: virtual void visit (AsyncBlockExpr &expr) override; virtual void visit (InlineAsm &expr) override; virtual void visit (LlvmInlineAsm &expr) override; + virtual void visit (OffsetOf &expr) override; virtual void visit (TypeParam ¶m) override; virtual void visit (ConstGenericParam ¶m) override; virtual void visit (LifetimeWhereClauseItem &item) override; diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc b/gcc/rust/hir/rust-ast-lower-expr.cc index 31126a8ad35..e9c9acc06c8 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.cc +++ b/gcc/rust/hir/rust-ast-lower-expr.cc @@ -1059,8 +1059,16 @@ ASTLoweringExpr::visit (AST::FormatArgs &fmt) void ASTLoweringExpr::visit (AST::OffsetOf &offset_of) { - // FIXME: Implement HIR::OffsetOf node and const evaluation - rust_unreachable (); + auto type = std::unique_ptr<Type> ( + ASTLoweringType::translate (offset_of.get_type ())); + + auto crate_num = mappings.get_current_crate (); + Analysis::NodeMapping mapping (crate_num, offset_of.get_node_id (), + mappings.get_next_hir_id (crate_num), + mappings.get_next_localdef_id (crate_num)); + + translated = new HIR::OffsetOf (std::move (type), offset_of.get_field (), + mapping, offset_of.get_locus ()); } } // namespace HIR diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc index 3d61de9e8bd..afee7b42f47 100644 --- a/gcc/rust/hir/rust-hir-dump.cc +++ b/gcc/rust/hir/rust-hir-dump.cc @@ -1602,6 +1602,17 @@ void Dump::visit (LlvmInlineAsm &e) {} +void +Dump::visit (OffsetOf &e) +{ + begin ("OffsetOf"); + + put_field ("type", e.get_type ().as_string ()); + put_field ("field", e.get_field ()); + + end ("OffsetOf"); +} + void Dump::visit (TypeParam &e) { diff --git a/gcc/rust/hir/rust-hir-dump.h b/gcc/rust/hir/rust-hir-dump.h index 8c39f489baf..3e6ae3006a7 100644 --- a/gcc/rust/hir/rust-hir-dump.h +++ b/gcc/rust/hir/rust-hir-dump.h @@ -169,6 +169,7 @@ private: virtual void visit (AsyncBlockExpr &) override; virtual void visit (InlineAsm &) override; virtual void visit (LlvmInlineAsm &) override; + virtual void visit (OffsetOf &) override; virtual void visit (TypeParam &) override; virtual void visit (ConstGenericParam &) override; diff --git a/gcc/rust/hir/tree/rust-hir-expr-abstract.h b/gcc/rust/hir/tree/rust-hir-expr-abstract.h index 8272a82808c..371daa835a2 100644 --- a/gcc/rust/hir/tree/rust-hir-expr-abstract.h +++ b/gcc/rust/hir/tree/rust-hir-expr-abstract.h @@ -74,6 +74,7 @@ public: Path, InlineAsm, LlvmInlineAsm, + OffsetOf, }; BaseKind get_hir_kind () override final { return Node::BaseKind::EXPR; } diff --git a/gcc/rust/hir/tree/rust-hir-expr.cc b/gcc/rust/hir/tree/rust-hir-expr.cc index 8544ed6708b..14786adf6f3 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.cc +++ b/gcc/rust/hir/tree/rust-hir-expr.cc @@ -1526,5 +1526,41 @@ InlineAsm::InlineAsm (location_t locus, bool is_global_asm, clobber_abi (std::move (clobber_abi)), options (std::move (options)) {} +OffsetOf & +OffsetOf::operator= (const OffsetOf &other) +{ + ExprWithoutBlock::operator= (other); + + type = other.type->clone_type (); + field = other.field; + loc = other.loc; + + return *this; +} + +ExprWithoutBlock * +OffsetOf::clone_expr_without_block_impl () const +{ + return new OffsetOf (*this); +} + +std::string +OffsetOf::as_string () const +{ + return "OffsetOf(" + type->as_string () + ", " + field.as_string () + ")"; +} + +void +OffsetOf::accept_vis (HIRExpressionVisitor &vis) +{ + vis.visit (*this); +} + +void +OffsetOf::accept_vis (HIRFullVisitor &vis) +{ + vis.visit (*this); +} + } // namespace HIR } // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index 64d01ee6f00..61e35905ea0 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -3236,6 +3236,42 @@ public: AST::AttrVec outer_attribs = AST::AttrVec ()); }; +class OffsetOf : public ExprWithoutBlock +{ +public: + OffsetOf (std::unique_ptr<Type> &&type, Identifier field, + Analysis::NodeMapping mappings, location_t loc) + : ExprWithoutBlock (mappings), type (std::move (type)), field (field), + loc (loc) + {} + + OffsetOf (const OffsetOf &other) + : ExprWithoutBlock (other), type (other.type->clone_type ()), + field (other.field), loc (other.loc) + {} + + OffsetOf &operator= (const OffsetOf &other); + + ExprWithoutBlock *clone_expr_without_block_impl () const override; + std::string as_string () const override; + + void accept_vis (HIRExpressionVisitor &vis) override; + void accept_vis (HIRFullVisitor &vis) override; + + ExprType get_expression_type () const override { return ExprType::OffsetOf; } + + location_t get_locus () const override { return loc; } + + Type &get_type () { return *type; } + const Type &get_type () const { return *type; } + const Identifier &get_field () const { return field; } + +private: + std::unique_ptr<Type> type; + Identifier field; + location_t loc; +}; + struct LlvmOperand { std::string constraint; diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h index 2905117dcb7..57b3a4d0915 100644 --- a/gcc/rust/hir/tree/rust-hir-full-decls.h +++ b/gcc/rust/hir/tree/rust-hir-full-decls.h @@ -128,6 +128,7 @@ class InlineAsmRegClass; class InlineAsmOperand; class InlineAsm; class LlvmInlineAsm; +class OffsetOf; // rust-stmt.h class EmptyStmt; diff --git a/gcc/rust/hir/tree/rust-hir-visitor.cc b/gcc/rust/hir/tree/rust-hir-visitor.cc index 77b96e547af..c77300aae3a 100644 --- a/gcc/rust/hir/tree/rust-hir-visitor.cc +++ b/gcc/rust/hir/tree/rust-hir-visitor.cc @@ -603,6 +603,12 @@ DefaultHIRVisitor::walk (LlvmInlineAsm &expr) input.expr->accept_vis (*this); } +void +DefaultHIRVisitor::walk (OffsetOf &expr) +{ + expr.get_type ().accept_vis (*this); +} + void DefaultHIRVisitor::walk (TypeParam ¶m) { diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h index 544cf5128a5..79962604607 100644 --- a/gcc/rust/hir/tree/rust-hir-visitor.h +++ b/gcc/rust/hir/tree/rust-hir-visitor.h @@ -88,6 +88,7 @@ public: virtual void visit (AsyncBlockExpr &expr) = 0; virtual void visit (InlineAsm &expr) = 0; virtual void visit (LlvmInlineAsm &expr) = 0; + virtual void visit (OffsetOf &expr) = 0; virtual void visit (TypeParam ¶m) = 0; virtual void visit (ConstGenericParam ¶m) = 0; virtual void visit (LifetimeWhereClauseItem &item) = 0; @@ -254,6 +255,7 @@ public: virtual void visit (AsyncBlockExpr &node) override { walk (node); } virtual void visit (InlineAsm &node) override { walk (node); } virtual void visit (LlvmInlineAsm &node) override { walk (node); } + virtual void visit (OffsetOf &node) override { walk (node); } virtual void visit (TypeParam &node) override { walk (node); } virtual void visit (ConstGenericParam &node) override { walk (node); } virtual void visit (LifetimeWhereClauseItem &node) override { walk (node); } @@ -392,6 +394,7 @@ protected: virtual void walk (AsyncBlockExpr &) final; virtual void walk (InlineAsm &) final; virtual void walk (LlvmInlineAsm &) final; + virtual void walk (OffsetOf &) final; virtual void walk (TypeParam &) final; virtual void walk (ConstGenericParam &) final; virtual void walk (LifetimeWhereClauseItem &) final; @@ -531,6 +534,7 @@ public: virtual void visit (AsyncBlockExpr &) override {} virtual void visit (InlineAsm &) override {} virtual void visit (LlvmInlineAsm &) override {} + virtual void visit (OffsetOf &) override {} virtual void visit (TypeParam &) override {} virtual void visit (ConstGenericParam &) override {} @@ -754,6 +758,7 @@ public: virtual void visit (IfExpr &expr) = 0; virtual void visit (IfExprConseqElse &expr) = 0; virtual void visit (InlineAsm &expr) = 0; + virtual void visit (OffsetOf &expr) = 0; virtual void visit (LlvmInlineAsm &expr) = 0; virtual void visit (MatchExpr &expr) = 0; virtual void visit (AwaitExpr &expr) = 0; diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc index ead751a0a7d..4a105e77d91 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -895,6 +895,19 @@ TypeCheckExpr::visit (HIR::LlvmInlineAsm &expr) infered = TyTy::TupleType::get_unit_type (); } +void +TypeCheckExpr::visit (HIR::OffsetOf &expr) +{ + TypeCheckType::Resolve (expr.get_type ()); + + // FIXME: Does offset_of always return a usize? + TyTy::BaseType *size_ty; + bool ok = context->lookup_builtin ("usize", &size_ty); + rust_assert (ok); + + infered = size_ty; +} + void TypeCheckExpr::visit (HIR::RangeFullExpr &expr) { diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index 48f28c70079..0343922407e 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -19,6 +19,7 @@ #ifndef RUST_HIR_TYPE_CHECK_EXPR #define RUST_HIR_TYPE_CHECK_EXPR +#include "rust-hir-expr.h" #include "rust-hir-type-check-base.h" #include "rust-hir-visitor.h" #include "rust-tyty.h" @@ -78,6 +79,7 @@ public: void visit (HIR::ClosureExpr &expr) override; void visit (HIR::InlineAsm &expr) override; void visit (HIR::LlvmInlineAsm &expr) override; + void visit (HIR::OffsetOf &expr) override; // TODO void visit (HIR::ErrorPropagationExpr &) override {} diff --git a/gcc/testsuite/rust/compile/offset_of2.rs b/gcc/testsuite/rust/compile/offset_of2.rs new file mode 100644 index 00000000000..d4ad9c2db31 --- /dev/null +++ b/gcc/testsuite/rust/compile/offset_of2.rs @@ -0,0 +1,9 @@ +// { dg-additional-options "-frust-compile-until=compilation -frust-assume-builtin-offset-of" } + +pub struct Foo { + a: i32, +} + +fn main() { + let _ = offset_of!(Foo, a); // valid +} -- 2.49.0