#define RUST_COMPILE_BLOCK
#include "rust-compile-base.h"
+#include "rust-hir-expr.h"
#include "rust-hir-visitor.h"
namespace Rust {
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)
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:
ctx->add_statement (asm_codegen.tree_codegen_asm (expr));
}
+void
+CompileExpr::visit (HIR::OffsetOf &expr)
+{
+ rust_unreachable ();
+}
+
void
CompileExpr::visit (HIR::IfExprConseqElse &expr)
{
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 {}
ExprStmtBuilder::visit (HIR::LlvmInlineAsm &expr)
{}
+void
+ExprStmtBuilder::visit (HIR::OffsetOf &expr)
+{}
+
void
ExprStmtBuilder::visit (HIR::MethodCallExpr &expr)
{}
#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"
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;
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
#include "rust-bir-builder-internal.h"
#include "rust-bir-builder-expr-stmt.h"
+#include "rust-hir-expr.h"
namespace Rust {
namespace BIR {
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
#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"
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 {}
PrivacyReporter::visit (HIR::LlvmInlineAsm &)
{}
+void
+PrivacyReporter::visit (HIR::OffsetOf &expr)
+{
+ // TODO: Do we have to do anything?
+}
+
void
PrivacyReporter::visit (HIR::TypePath &path)
{
#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"
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 &);
ConstChecker::visit (LlvmInlineAsm &)
{}
+void
+ConstChecker::visit (OffsetOf &)
+{}
+
void
ConstChecker::visit (TypeParam &)
{}
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;
PatternChecker::visit (LlvmInlineAsm &expr)
{}
+void
+PatternChecker::visit (OffsetOf &expr)
+{}
+
void
PatternChecker::visit (TypeParam &)
{}
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;
"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 &)
{}
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;
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
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)
{
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;
Path,
InlineAsm,
LlvmInlineAsm,
+ OffsetOf,
};
BaseKind get_hir_kind () override final { return Node::BaseKind::EXPR; }
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
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;
class InlineAsmOperand;
class InlineAsm;
class LlvmInlineAsm;
+class OffsetOf;
// rust-stmt.h
class EmptyStmt;
input.expr->accept_vis (*this);
}
+void
+DefaultHIRVisitor::walk (OffsetOf &expr)
+{
+ expr.get_type ().accept_vis (*this);
+}
+
void
DefaultHIRVisitor::walk (TypeParam ¶m)
{
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;
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); }
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;
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 {}
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;
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)
{
#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"
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 {}
--- /dev/null
+// { 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
+}