aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorM V V S Manoj Kumar <mvvsmanojkumar@gmail.com>2021-11-20 08:01:36 +0530
committerGitHub <noreply@github.com>2021-11-20 08:01:36 +0530
commit73a0903c156f86e1e59c30c542780fe2162438d4 (patch)
treed608a5ee3f316d63f259113ae7fed2da4149a6ce
parent9c4e3db7789dc32ae08a2302b13c2772f51d5bea (diff)
parentfece068309e8a3cbeb81539fba14e1c970740a94 (diff)
downloadgcc-73a0903c156f86e1e59c30c542780fe2162438d4.zip
gcc-73a0903c156f86e1e59c30c542780fe2162438d4.tar.gz
gcc-73a0903c156f86e1e59c30c542780fe2162438d4.tar.bz2
Merge branch 'Rust-GCC:master' into master
-rw-r--r--.github/workflows/clang-format.yml1
-rw-r--r--CONTRIBUTING.md78
-rw-r--r--gcc/rust/Make-lang.in2
-rw-r--r--gcc/rust/ast/rust-ast.h19
-rw-r--r--gcc/rust/ast/rust-expr.h15
-rw-r--r--gcc/rust/backend/rust-compile-base.h18
-rw-r--r--gcc/rust/backend/rust-compile-block.h15
-rw-r--r--gcc/rust/backend/rust-compile-context.h191
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc393
-rw-r--r--gcc/rust/backend/rust-compile-expr.h197
-rw-r--r--gcc/rust/backend/rust-compile-extern.h12
-rw-r--r--gcc/rust/backend/rust-compile-fnparam.h16
-rw-r--r--gcc/rust/backend/rust-compile-implitem.h71
-rw-r--r--gcc/rust/backend/rust-compile-intrinsic.cc4
-rw-r--r--gcc/rust/backend/rust-compile-intrinsic.h2
-rw-r--r--gcc/rust/backend/rust-compile-item.h37
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc8
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.h21
-rw-r--r--gcc/rust/backend/rust-compile-stmt.h14
-rw-r--r--gcc/rust/backend/rust-compile-struct-field-expr.h4
-rw-r--r--gcc/rust/backend/rust-compile-tyty.h16
-rw-r--r--gcc/rust/backend/rust-compile-var-decl.h9
-rw-r--r--gcc/rust/backend/rust-compile.cc324
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h16
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.h23
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h79
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-test.cc67
-rw-r--r--gcc/rust/hir/tree/rust-hir-visitor.h1
-rw-r--r--gcc/rust/lint/rust-lint-marklive-base.h2
-rw-r--r--gcc/rust/lint/rust-lint-marklive.h6
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h27
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h3
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc38
-rw-r--r--gcc/rust/resolve/rust-ast-verify-assignee.h7
-rw-r--r--gcc/rust/rust-backend.h454
-rw-r--r--gcc/rust/rust-diagnostics.h4
-rw-r--r--gcc/rust/rust-gcc.cc1442
-rw-r--r--gcc/rust/typecheck/rust-autoderef.h41
-rw-r--r--gcc/rust/typecheck/rust-hir-const-fold-base.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-const-fold-ctx.h6
-rw-r--r--gcc/rust/typecheck/rust-hir-const-fold.cc20
-rw-r--r--gcc/rust/typecheck/rust-hir-const-fold.h88
-rw-r--r--gcc/rust/typecheck/rust-hir-path-probe.h30
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc2
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.h26
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h292
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.h23
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.h8
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-stmt.h3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-util.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.h90
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.cc49
-rw-r--r--gcc/rust/typecheck/rust-substitution-mapper.h8
-rw-r--r--gcc/rust/typecheck/rust-tyctx.cc13
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.h9
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc2
-rw-r--r--gcc/rust/typecheck/rust-tyty.h16
-rw-r--r--gcc/rust/util/rust-hir-map.cc6
-rw-r--r--gcc/rust/util/rust-hir-map.h201
-rw-r--r--gcc/rust/util/rust-mapping-common.h25
-rw-r--r--gcc/testsuite/rust/compile/torture/issue-808.rs22
-rw-r--r--gcc/testsuite/rust/compile/torture/traits11.rs1
-rw-r--r--gcc/testsuite/rust/compile/torture/traits4.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/traits5.rs2
-rw-r--r--gcc/testsuite/rust/compile/torture/traits6.rs1
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_1.rs39
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_2.rs41
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_3.rs58
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_4.rs35
-rw-r--r--gcc/testsuite/rust/execute/torture/operator_overload_5.rs35
71 files changed, 2836 insertions, 2000 deletions
diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml
index d37247c..e1c81ad 100644
--- a/.github/workflows/clang-format.yml
+++ b/.github/workflows/clang-format.yml
@@ -13,6 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
+ # If updating these steps, please also correspondingly update '../../CONTRIBUTING.md', "Running `clang-format` locally".
- uses: actions/checkout@v2
- name: Copy .clang-format file
run: cp contrib/clang-format .clang-format
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 360c0e2..c0d75d7 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -40,9 +40,81 @@ These will be imported into a GitHub PR to follow the normal review process, and
* Where possible please add test cases to `gcc/testsuite/rust/` for all PRs. Some issues may not be testable via dejagnu/automation such as debug dump changes.
-* PR's cannot be merged untill clang format and the build and tests pass.
-
-* Please take the time to create good git commit messages see the existing format of them in the git log or refer to something like: https://chris.beams.io/posts/git-commit/
+* Follow the [GCC coding style](https://gcc.gnu.org/codingconventions.html) (see `clang-format` below).
+
+* PRs won't be merged until the build and tests pass.
+
+* Please take the time to create good git commit messages. See the existing format of them in the git log or refer to something like: https://chris.beams.io/posts/git-commit/
+
+#### Running `clang-format` locally
+
+* on all files using python scripts
+... corresponding to what the _Clang Format Lint_ (`.github/workflows/clang-format.yml`) is doing, with `clang-format-10` being available locally, and avoiding the Docker overhead.
+
+```shell
+$ wget 'https://github.com/DoozyX/clang-format-lint-action/raw/v0.11/run-clang-format.py'
+$ cp contrib/clang-format .clang-format
+$ python3 run-clang-format.py --clang-format-executable clang-format-10 --recursive --extensions h,cc gcc/rust/
+```
+
+* on a given patch using python scripts
+See the [clang-format documentation](https://clang.llvm.org/docs/ClangFormat.html#script-for-patch-reformatting) :
+
+ $ git diff -U0 --no-color HEAD^ | clang-format-diff.py -i -p1
+
+* using `git` interface
+
+At least on Debian and its derivative, each `clang-format` packages also comes
+with `git-clang-format` command that can be used easily. It applies on staged
+changes, and any modification can be seen as unstaged changes:
+
+```diff
+$ git diff --cached
+diff --git a/gcc/rust/rust-abi.h b/gcc/rust/rust-abi.h
+index bd3043295ce..9559374ce60 100644
+--- a/gcc/rust/rust-abi.h
++++ b/gcc/rust/rust-abi.h
+@@ -22,10 +22,10 @@ namespace Rust {
+ enum ABI
+ {
+ UNKNOWN,
+- RUST,
++ RUST,
+ INTRINSIC,
+ C,
+- CDECL,
++ CDECL,
+ STDCALL,
+ FASTCALL,
+ };
+
+gccrs/gcc/rust on  dkm/clang_format [$!+?]
+❯ git clang-format
+changed files:
+ gcc/rust/rust-abi.h
+
+gccrs/gcc/rust on  dkm/clang_format [$!+?]
+$ git diff rust-abi.h
+diff --git a/gcc/rust/rust-abi.h b/gcc/rust/rust-abi.h
+index 9559374ce60..bd3043295ce 100644
+--- a/gcc/rust/rust-abi.h
++++ b/gcc/rust/rust-abi.h
+@@ -22,10 +22,10 @@ namespace Rust {
+ enum ABI
+ {
+ UNKNOWN,
+- RUST,
++ RUST,
+ INTRINSIC,
+ C,
+- CDECL,
++ CDECL,
+ STDCALL,
+ FASTCALL,
+ };
+```
+
+Also note that you can use a given version of `clang-format` by using `git clang-format-10` if you have installed that particular version.
Thanks! :heart: :heart: :heart:
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 15c0a8f..f0e9bc3 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -86,10 +86,12 @@ GRS_OBJS = \
rust/rust-hir-const-fold.o \
rust/rust-hir-type-check-type.o \
rust/rust-hir-type-check-struct.o \
+ rust/rust-substitution-mapper.o \
rust/rust-lint-marklive.o \
rust/rust-hir-type-check-path.o \
rust/rust-compile-intrinsic.o \
rust/rust-base62.o \
+ rust/rust-compile-expr.o \
$(END)
# removed object files from here
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 72f2609..05779e7 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -542,6 +542,13 @@ protected:
class AttrInput
{
public:
+ enum AttrInputType
+ {
+ LITERAL,
+ META_ITEM,
+ TOKEN_TREE,
+ };
+
virtual ~AttrInput () {}
// Unique pointer custom clone function
@@ -564,6 +571,8 @@ public:
// Returns whether attr input has been parsed to meta item syntax.
virtual bool is_meta_item () const = 0;
+ virtual AttrInputType get_attr_input_type () const = 0;
+
protected:
// pure virtual clone implementation
virtual AttrInput *clone_attr_input_impl () const = 0;
@@ -650,6 +659,11 @@ public:
bool check_cfg_predicate (const Session &session) const override;
+ AttrInputType get_attr_input_type () const final override
+ {
+ return AttrInput::AttrInputType::META_ITEM;
+ }
+
// Clones this object.
std::unique_ptr<AttrInputMetaItemContainer>
clone_attr_input_meta_item_container () const
@@ -767,6 +781,11 @@ public:
}
bool is_meta_item () const override { return false; }
+
+ AttrInputType get_attr_input_type () const final override
+ {
+ return AttrInput::AttrInputType::TOKEN_TREE;
+ }
};
/* Forward decl - definition moved to rust-expr.h as it requires LiteralExpr to
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 05c78b7..3463f5a 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -102,13 +102,7 @@ protected:
// Literal expression attribute body (non-macro attribute)
class AttrInputLiteral : public AttrInput
{
- // Literal expression WITHOUT SUFFIX
- // std::unique_ptr<LiteralExpr> literal_expr;
- LiteralExpr
- literal_expr; // as not using polymorphic behaviour, doesn't require pointer
- // TODO: will require pointer if LiteralExpr is changed to have subclassing
-
- // TODO: should this store location data?
+ LiteralExpr literal_expr;
public:
AttrInputLiteral (LiteralExpr lit_expr) : literal_expr (std::move (lit_expr))
@@ -127,6 +121,13 @@ public:
bool is_meta_item () const override { return false; }
+ LiteralExpr &get_literal () { return literal_expr; }
+
+ AttrInputType get_attr_input_type () const final override
+ {
+ return AttrInput::AttrInputType::LITERAL;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index 3184e27..af0ea40 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -193,23 +193,21 @@ protected:
Context *get_context () { return ctx; }
- void compile_function_body (Bfunction *fndecl,
+ void compile_function_body (tree fndecl,
std::unique_ptr<HIR::BlockExpr> &function_body,
bool has_return_type);
- bool compile_locals_for_block (Resolver::Rib &rib, Bfunction *fndecl,
+ bool compile_locals_for_block (Resolver::Rib &rib, tree fndecl,
std::vector<Bvariable *> &locals);
- Bexpression *coercion_site (Bexpression *compiled_ref, TyTy::BaseType *actual,
- TyTy::BaseType *expected, Location locus);
+ tree coercion_site (tree compiled_ref, TyTy::BaseType *actual,
+ TyTy::BaseType *expected, Location locus);
- Bexpression *coerce_to_dyn_object (Bexpression *compiled_ref,
- const TyTy::BaseType *actual,
- const TyTy::BaseType *expected,
- const TyTy::DynamicObjectType *ty,
- Location locus);
+ tree coerce_to_dyn_object (tree compiled_ref, const TyTy::BaseType *actual,
+ const TyTy::BaseType *expected,
+ const TyTy::DynamicObjectType *ty, Location locus);
- Bexpression *compute_address_for_trait_item (
+ tree compute_address_for_trait_item (
const Resolver::TraitItemReference *ref,
const TyTy::TypeBoundPredicate *predicate,
std::vector<std::pair<Resolver::TraitReference *, HIR::ImplBlock *>>
diff --git a/gcc/rust/backend/rust-compile-block.h b/gcc/rust/backend/rust-compile-block.h
index 6876e8a..af90671 100644
--- a/gcc/rust/backend/rust-compile-block.h
+++ b/gcc/rust/backend/rust-compile-block.h
@@ -30,7 +30,7 @@ class CompileBlock : public HIRCompileBase
using Rust::Compile::HIRCompileBase::visit;
public:
- static Bblock *compile (HIR::BlockExpr *expr, Context *ctx, Bvariable *result)
+ static tree compile (HIR::BlockExpr *expr, Context *ctx, Bvariable *result)
{
CompileBlock compiler (ctx, result);
expr->accept_vis (compiler);
@@ -44,7 +44,7 @@ private:
: HIRCompileBase (ctx), translated (nullptr), result (result)
{}
- Bblock *translated;
+ tree translated;
Bvariable *result;
};
@@ -53,8 +53,7 @@ class CompileConditionalBlocks : public HIRCompileBase
using Rust::Compile::HIRCompileBase::visit;
public:
- static Bstatement *compile (HIR::IfExpr *expr, Context *ctx,
- Bvariable *result)
+ static tree compile (HIR::IfExpr *expr, Context *ctx, Bvariable *result)
{
CompileConditionalBlocks resolver (ctx, result);
expr->accept_vis (resolver);
@@ -72,7 +71,7 @@ private:
: HIRCompileBase (ctx), translated (nullptr), result (result)
{}
- Bstatement *translated;
+ tree translated;
Bvariable *result;
};
@@ -81,8 +80,8 @@ class CompileExprWithBlock : public HIRCompileBase
using Rust::Compile::HIRCompileBase::visit;
public:
- static Bstatement *compile (HIR::ExprWithBlock *expr, Context *ctx,
- Bvariable *result)
+ static tree compile (HIR::ExprWithBlock *expr, Context *ctx,
+ Bvariable *result)
{
CompileExprWithBlock resolver (ctx, result);
expr->accept_vis (resolver);
@@ -109,7 +108,7 @@ private:
: HIRCompileBase (ctx), translated (nullptr), result (result)
{}
- Bstatement *translated;
+ tree translated;
Bvariable *result;
};
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index 396cb10..668e8ba 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -35,7 +35,7 @@ namespace Compile {
struct fncontext
{
- ::Bfunction *fndecl;
+ tree fndecl;
::Bvariable *ret_addr;
};
@@ -60,20 +60,20 @@ public:
ok = tyctx->lookup_type (ref, &lookup);
rust_assert (ok);
- Btype *compiled = TyTyCompile::compile (backend, lookup);
- compiled_type_map.insert (std::pair<HirId, Btype *> (ref, compiled));
+ tree compiled = TyTyCompile::compile (backend, lookup);
+ compiled_type_map.insert (std::pair<HirId, tree> (ref, compiled));
builtin_range.insert (ref);
}
}
- bool lookup_compiled_types (HirId id, ::Btype **type,
+ bool lookup_compiled_types (HirId id, tree *type,
const TyTy::BaseType *ref = nullptr)
{
if (ref != nullptr)
{
for (auto it = mono.begin (); it != mono.end (); it++)
{
- std::pair<HirId, ::Btype *> &val = it->second;
+ std::pair<HirId, tree> &val = it->second;
const TyTy::BaseType *r = it->first;
if (ref->is_equal (*r))
@@ -94,14 +94,14 @@ public:
return true;
}
- void insert_compiled_type (HirId id, ::Btype *type,
+ void insert_compiled_type (HirId id, tree type,
const TyTy::BaseType *ref = nullptr)
{
rust_assert (builtin_range.find (id) == builtin_range.end ());
- compiled_type_map.insert (std::pair<HirId, Btype *> (id, type));
+ compiled_type_map.insert (std::pair<HirId, tree> (id, type));
if (ref != nullptr)
{
- std::pair<HirId, ::Btype *> elem (id, type);
+ std::pair<HirId, tree> elem (id, type);
mono[ref] = std::move (elem);
}
}
@@ -112,13 +112,13 @@ public:
Analysis::Mappings *get_mappings () { return mappings; }
ConstFold::Context *get_const_ctx () { return const_ctx; }
- void push_block (Bblock *scope)
+ void push_block (tree scope)
{
scope_stack.push_back (scope);
statements.push_back ({});
}
- Bblock *pop_block ()
+ tree pop_block ()
{
auto block = scope_stack.back ();
scope_stack.pop_back ();
@@ -131,7 +131,7 @@ public:
return block;
}
- Bblock *peek_enclosing_scope ()
+ tree peek_enclosing_scope ()
{
if (scope_stack.size () == 0)
return nullptr;
@@ -139,12 +139,12 @@ public:
return scope_stack.back ();
}
- void add_statement_to_enclosing_scope (Bstatement *stmt)
+ void add_statement_to_enclosing_scope (tree stmt)
{
statements.at (statements.size () - 2).push_back (stmt);
}
- void add_statement (Bstatement *stmt) { statements.back ().push_back (stmt); }
+ void add_statement (tree stmt) { statements.back ().push_back (stmt); }
void insert_var_decl (HirId id, ::Bvariable *decl)
{
@@ -161,7 +161,7 @@ public:
return true;
}
- void insert_function_decl (const TyTy::FnType *ref, ::Bfunction *fn)
+ void insert_function_decl (const TyTy::FnType *ref, tree fn)
{
auto id = ref->get_ty_ref ();
auto dId = ref->get_id ();
@@ -176,8 +176,7 @@ public:
mono_fns[dId].push_back ({ref, fn});
}
- bool lookup_function_decl (HirId id, ::Bfunction **fn,
- DefId dId = UNKNOWN_DEFID,
+ bool lookup_function_decl (HirId id, tree *fn, DefId dId = UNKNOWN_DEFID,
const TyTy::BaseType *ref = nullptr)
{
// for for any monomorphized fns
@@ -192,7 +191,7 @@ public:
for (auto &e : mono_fns[dId])
{
const TyTy::BaseType *r = e.first;
- ::Bfunction *f = e.second;
+ tree f = e.second;
if (ref->is_equal (*r))
{
*fn = f;
@@ -210,12 +209,9 @@ public:
return true;
}
- void insert_const_decl (HirId id, ::Bexpression *expr)
- {
- compiled_consts[id] = expr;
- }
+ void insert_const_decl (HirId id, tree expr) { compiled_consts[id] = expr; }
- bool lookup_const_decl (HirId id, ::Bexpression **expr)
+ bool lookup_const_decl (HirId id, tree *expr)
{
auto it = compiled_consts.find (id);
if (it == compiled_consts.end ())
@@ -225,12 +221,9 @@ public:
return true;
}
- void insert_label_decl (HirId id, ::Blabel *label)
- {
- compiled_labels[id] = label;
- }
+ void insert_label_decl (HirId id, tree label) { compiled_labels[id] = label; }
- bool lookup_label_decl (HirId id, ::Blabel **label)
+ bool lookup_label_decl (HirId id, tree *label)
{
auto it = compiled_labels.find (id);
if (it == compiled_labels.end ())
@@ -240,17 +233,17 @@ public:
return true;
}
- void push_fn (::Bfunction *fn, ::Bvariable *ret_addr)
+ void push_fn (tree fn, ::Bvariable *ret_addr)
{
fn_stack.push_back (fncontext{fn, ret_addr});
}
void pop_fn () { fn_stack.pop_back (); }
fncontext peek_fn () { return fn_stack.back (); }
- void push_type (::Btype *t) { type_decls.push_back (t); }
+ void push_type (tree t) { type_decls.push_back (t); }
void push_var (::Bvariable *v) { var_decls.push_back (v); }
- void push_const (::Bexpression *c) { const_decls.push_back (c); }
- void push_function (::Bfunction *f) { func_decls.push_back (f); }
+ void push_const (tree c) { const_decls.push_back (c); }
+ void push_function (tree f) { func_decls.push_back (f); }
void write_to_backend ()
{
@@ -258,11 +251,11 @@ public:
var_decls);
}
- bool function_completed (Bfunction *fn)
+ bool function_completed (tree fn)
{
for (auto it = func_decls.begin (); it != func_decls.end (); it++)
{
- Bfunction *i = (*it);
+ tree i = (*it);
if (i == fn)
{
return true;
@@ -282,16 +275,16 @@ public:
return back;
}
- void push_loop_begin_label (Blabel *label)
+ void push_loop_begin_label (tree label)
{
loop_begin_labels.push_back (label);
}
- Blabel *peek_loop_begin_label () { return loop_begin_labels.back (); }
+ tree peek_loop_begin_label () { return loop_begin_labels.back (); }
- Blabel *pop_loop_begin_label ()
+ tree pop_loop_begin_label ()
{
- Blabel *pop = loop_begin_labels.back ();
+ tree pop = loop_begin_labels.back ();
loop_begin_labels.pop_back ();
return pop;
}
@@ -322,30 +315,30 @@ private:
// state
std::vector<fncontext> fn_stack;
std::map<HirId, ::Bvariable *> compiled_var_decls;
- std::map<HirId, ::Btype *> compiled_type_map;
- std::map<HirId, ::Bfunction *> compiled_fn_map;
- std::map<HirId, ::Bexpression *> compiled_consts;
- std::map<HirId, ::Blabel *> compiled_labels;
- std::vector<::std::vector<Bstatement *>> statements;
- std::vector<::Bblock *> scope_stack;
+ std::map<HirId, tree> compiled_type_map;
+ std::map<HirId, tree> compiled_fn_map;
+ std::map<HirId, tree> compiled_consts;
+ std::map<HirId, tree> compiled_labels;
+ std::vector<::std::vector<tree>> statements;
+ std::vector<tree> scope_stack;
std::vector<::Bvariable *> loop_value_stack;
- std::vector<::Blabel *> loop_begin_labels;
- std::map<const TyTy::BaseType *, std::pair<HirId, ::Btype *>> mono;
- std::map<DefId, std::vector<std::pair<const TyTy::BaseType *, ::Bfunction *>>>
+ std::vector<tree> loop_begin_labels;
+ std::map<const TyTy::BaseType *, std::pair<HirId, tree>> mono;
+ std::map<DefId, std::vector<std::pair<const TyTy::BaseType *, tree>>>
mono_fns;
// To GCC middle-end
- std::vector<::Btype *> type_decls;
+ std::vector<tree> type_decls;
std::vector<::Bvariable *> var_decls;
- std::vector<::Bexpression *> const_decls;
- std::vector<::Bfunction *> func_decls;
+ std::vector<tree> const_decls;
+ std::vector<tree> func_decls;
};
class TyTyResolveCompile : public TyTy::TyConstVisitor
{
public:
- static ::Btype *compile (Context *ctx, const TyTy::BaseType *ty,
- bool trait_object_mode = false)
+ static tree compile (Context *ctx, const TyTy::BaseType *ty,
+ bool trait_object_mode = false)
{
TyTyResolveCompile compiler (ctx, trait_object_mode);
ty->accept_vis (compiler);
@@ -375,16 +368,16 @@ public:
void visit (const TyTy::FnType &type) override
{
- Backend::Btyped_identifier receiver;
- std::vector<Backend::Btyped_identifier> parameters;
- std::vector<Backend::Btyped_identifier> results;
+ Backend::typed_identifier receiver;
+ std::vector<Backend::typed_identifier> parameters;
+ std::vector<Backend::typed_identifier> results;
if (!type.get_return_type ()->is_unit ())
{
auto hir_type = type.get_return_type ();
auto ret
= TyTyResolveCompile::compile (ctx, hir_type, trait_object_mode);
- results.push_back (Backend::Btyped_identifier (
+ results.push_back (Backend::typed_identifier (
"_", ret,
ctx->get_mappings ()->lookup_location (hir_type->get_ref ())));
}
@@ -395,7 +388,7 @@ public:
auto compiled_param_type
= TyTyResolveCompile::compile (ctx, param_tyty, trait_object_mode);
- auto compiled_param = Backend::Btyped_identifier (
+ auto compiled_param = Backend::typed_identifier (
param_pair.first->as_string (), compiled_param_type,
ctx->get_mappings ()->lookup_location (param_tyty->get_ref ()));
@@ -414,12 +407,12 @@ public:
void visit (const TyTy::FnPtr &type) override
{
- Btype *result_type
+ tree result_type
= TyTyResolveCompile::compile (ctx, type.get_return_type ());
- std::vector<Btype *> parameters;
+ std::vector<tree> parameters;
type.iterate_params ([&] (TyTy::BaseType *p) mutable -> bool {
- Btype *pty = TyTyResolveCompile::compile (ctx, p);
+ tree pty = TyTyResolveCompile::compile (ctx, p);
parameters.push_back (pty);
return true;
});
@@ -439,25 +432,25 @@ public:
rust_assert (type.number_of_variants () == 1);
TyTy::VariantDef &variant = *type.get_variants ().at (0);
- std::vector<Backend::Btyped_identifier> fields;
+ std::vector<Backend::typed_identifier> fields;
for (size_t i = 0; i < variant.num_fields (); i++)
{
const TyTy::StructFieldType *field = variant.get_field_at_index (i);
- Btype *compiled_field_ty
+ tree compiled_field_ty
= TyTyResolveCompile::compile (ctx, field->get_field_type ());
- Backend::Btyped_identifier f (field->get_name (), compiled_field_ty,
- ctx->get_mappings ()->lookup_location (
- type.get_ty_ref ()));
+ Backend::typed_identifier f (field->get_name (), compiled_field_ty,
+ ctx->get_mappings ()->lookup_location (
+ type.get_ty_ref ()));
fields.push_back (std::move (f));
}
- Btype *type_record;
+ tree type_record;
if (type.is_union ())
type_record = ctx->get_backend ()->union_type (fields);
else
type_record = ctx->get_backend ()->struct_type (fields);
- Btype *named_struct
+ tree named_struct
= ctx->get_backend ()->named_type (type.get_name (), type_record,
ctx->get_mappings ()->lookup_location (
type.get_ty_ref ()));
@@ -482,11 +475,11 @@ public:
return;
// create implicit struct
- std::vector<Backend::Btyped_identifier> fields;
+ std::vector<Backend::typed_identifier> fields;
for (size_t i = 0; i < type.num_fields (); i++)
{
TyTy::BaseType *field = type.get_field (i);
- Btype *compiled_field_ty = TyTyResolveCompile::compile (ctx, field);
+ tree compiled_field_ty = TyTyResolveCompile::compile (ctx, field);
// rustc uses the convention __N, where N is an integer, to
// name the fields of a tuple. We follow this as well,
@@ -494,15 +487,15 @@ public:
// this, rather than simply emitting the integer, is that this
// approach makes it simpler to use a C-only debugger, or
// GDB's C mode, when debugging Rust.
- Backend::Btyped_identifier f ("__" + std::to_string (i),
- compiled_field_ty,
- ctx->get_mappings ()->lookup_location (
- type.get_ty_ref ()));
+ Backend::typed_identifier f ("__" + std::to_string (i),
+ compiled_field_ty,
+ ctx->get_mappings ()->lookup_location (
+ type.get_ty_ref ()));
fields.push_back (std::move (f));
}
- Btype *struct_type_record = ctx->get_backend ()->struct_type (fields);
- Btype *named_struct
+ tree struct_type_record = ctx->get_backend ()->struct_type (fields);
+ tree named_struct
= ctx->get_backend ()->named_type (type.as_string (), struct_type_record,
ctx->get_mappings ()->lookup_location (
type.get_ty_ref ()));
@@ -514,7 +507,7 @@ public:
void visit (const TyTy::ArrayType &type) override
{
- Btype *element_type
+ tree element_type
= TyTyResolveCompile::compile (ctx, type.get_element_type ());
translated
= ctx->get_backend ()->array_type (element_type, type.get_capacity ());
@@ -522,7 +515,7 @@ public:
void visit (const TyTy::BoolType &type) override
{
- ::Btype *compiled_type = nullptr;
+ tree compiled_type = nullptr;
bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
rust_assert (ok);
translated = compiled_type;
@@ -530,7 +523,7 @@ public:
void visit (const TyTy::IntType &type) override
{
- ::Btype *compiled_type = nullptr;
+ tree compiled_type = nullptr;
bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
rust_assert (ok);
translated = compiled_type;
@@ -538,7 +531,7 @@ public:
void visit (const TyTy::UintType &type) override
{
- ::Btype *compiled_type = nullptr;
+ tree compiled_type = nullptr;
bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
rust_assert (ok);
translated = compiled_type;
@@ -546,7 +539,7 @@ public:
void visit (const TyTy::FloatType &type) override
{
- ::Btype *compiled_type = nullptr;
+ tree compiled_type = nullptr;
bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
rust_assert (ok);
translated = compiled_type;
@@ -554,7 +547,7 @@ public:
void visit (const TyTy::USizeType &type) override
{
- ::Btype *compiled_type = nullptr;
+ tree compiled_type = nullptr;
bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
rust_assert (ok);
translated = compiled_type;
@@ -562,7 +555,7 @@ public:
void visit (const TyTy::ISizeType &type) override
{
- ::Btype *compiled_type = nullptr;
+ tree compiled_type = nullptr;
bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
rust_assert (ok);
translated = compiled_type;
@@ -570,7 +563,7 @@ public:
void visit (const TyTy::CharType &type) override
{
- ::Btype *compiled_type = nullptr;
+ tree compiled_type = nullptr;
bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
rust_assert (ok);
translated = compiled_type;
@@ -578,7 +571,7 @@ public:
void visit (const TyTy::ReferenceType &type) override
{
- Btype *base_compiled_type
+ tree base_compiled_type
= TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
if (type.is_mutable ())
{
@@ -593,7 +586,7 @@ public:
void visit (const TyTy::PointerType &type) override
{
- Btype *base_compiled_type
+ tree base_compiled_type
= TyTyResolveCompile::compile (ctx, type.get_base (), trait_object_mode);
if (type.is_mutable ())
{
@@ -608,7 +601,7 @@ public:
void visit (const TyTy::StrType &type) override
{
- ::Btype *compiled_type = nullptr;
+ tree compiled_type = nullptr;
bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
rust_assert (ok);
translated = compiled_type;
@@ -633,32 +626,32 @@ public:
// create implicit struct
auto items = type.get_object_items ();
- std::vector<Backend::Btyped_identifier> fields;
+ std::vector<Backend::typed_identifier> fields;
- Btype *uint = ctx->get_backend ()->integer_type (
+ tree uint = ctx->get_backend ()->integer_type (
true, ctx->get_backend ()->get_pointer_size ());
- Btype *uintptr_ty = ctx->get_backend ()->pointer_type (uint);
+ tree uintptr_ty = ctx->get_backend ()->pointer_type (uint);
- Backend::Btyped_identifier f ("__receiver_trait_obj_ptr", uintptr_ty,
- ctx->get_mappings ()->lookup_location (
- type.get_ty_ref ()));
+ Backend::typed_identifier f ("__receiver_trait_obj_ptr", uintptr_ty,
+ ctx->get_mappings ()->lookup_location (
+ type.get_ty_ref ()));
fields.push_back (std::move (f));
for (size_t i = 0; i < items.size (); i++)
{
// mrustc seems to make a vtable consisting of uintptr's
- Btype *uint = ctx->get_backend ()->integer_type (
+ tree uint = ctx->get_backend ()->integer_type (
true, ctx->get_backend ()->get_pointer_size ());
- Btype *uintptr_ty = ctx->get_backend ()->pointer_type (uint);
+ tree uintptr_ty = ctx->get_backend ()->pointer_type (uint);
- Backend::Btyped_identifier f ("__" + std::to_string (i), uintptr_ty,
- ctx->get_mappings ()->lookup_location (
- type.get_ty_ref ()));
+ Backend::typed_identifier f ("__" + std::to_string (i), uintptr_ty,
+ ctx->get_mappings ()->lookup_location (
+ type.get_ty_ref ()));
fields.push_back (std::move (f));
}
- Btype *type_record = ctx->get_backend ()->struct_type (fields);
- Btype *named_struct
+ tree type_record = ctx->get_backend ()->struct_type (fields);
+ tree named_struct
= ctx->get_backend ()->named_type (type.get_name (), type_record,
ctx->get_mappings ()->lookup_location (
type.get_ty_ref ()));
@@ -679,7 +672,7 @@ private:
Context *ctx;
bool trait_object_mode;
- ::Btype *translated;
+ tree translated;
size_t recursion_count;
static const size_t kDefaultRecusionLimit = 5;
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
new file mode 100644
index 0000000..fb01d8d
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -0,0 +1,393 @@
+// Copyright (C) 2020-2021 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-compile.h"
+#include "rust-compile-item.h"
+#include "rust-compile-expr.h"
+#include "rust-compile-struct-field-expr.h"
+#include "rust-hir-trait-resolve.h"
+#include "rust-hir-path-probe.h"
+#include "rust-hir-type-bounds.h"
+#include "rust-hir-dot-operator.h"
+
+namespace Rust {
+namespace Compile {
+
+void
+CompileExpr::visit (HIR::ArithmeticOrLogicalExpr &expr)
+{
+ auto op = expr.get_expr_type ();
+ auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
+ auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
+
+ // this might be an operator overload situation lets check
+ TyTy::FnType *fntype;
+ bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
+ expr.get_mappings ().get_hirid (), &fntype);
+ if (is_op_overload)
+ {
+ auto lang_item_type
+ = Analysis::RustLangItem::OperatorToLangItem (expr.get_expr_type ());
+ translated = resolve_operator_overload (lang_item_type, expr, lhs, rhs,
+ expr.get_lhs (), expr.get_rhs ());
+ return;
+ }
+
+ translated
+ = ctx->get_backend ()->arithmetic_or_logical_expression (op, lhs, rhs,
+ expr.get_locus ());
+}
+
+void
+CompileExpr::visit (HIR::CompoundAssignmentExpr &expr)
+{
+ fncontext fn = ctx->peek_fn ();
+
+ auto op = expr.get_expr_type ();
+ auto lhs = CompileExpr::Compile (expr.get_left_expr ().get (), ctx);
+ auto rhs = CompileExpr::Compile (expr.get_right_expr ().get (), ctx);
+
+ // this might be an operator overload situation lets check
+ TyTy::FnType *fntype;
+ bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
+ expr.get_mappings ().get_hirid (), &fntype);
+ if (is_op_overload)
+ {
+ auto lang_item_type
+ = Analysis::RustLangItem::CompoundAssignmentOperatorToLangItem (
+ expr.get_expr_type ());
+ auto compound_assignment
+ = resolve_operator_overload (lang_item_type, expr, lhs, rhs,
+ expr.get_left_expr ().get (),
+ expr.get_right_expr ().get ());
+ auto assignment
+ = ctx->get_backend ()->expression_statement (fn.fndecl,
+ compound_assignment);
+ ctx->add_statement (assignment);
+
+ return;
+ }
+
+ auto operator_expr
+ = ctx->get_backend ()->arithmetic_or_logical_expression (op, lhs, rhs,
+ expr.get_locus ());
+ tree assignment
+ = ctx->get_backend ()->assignment_statement (fn.fndecl, lhs, operator_expr,
+ expr.get_locus ());
+ ctx->add_statement (assignment);
+}
+
+void
+CompileExpr::visit (HIR::NegationExpr &expr)
+{
+ auto op = expr.get_expr_type ();
+ auto negated_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
+ auto location = expr.get_locus ();
+
+ // this might be an operator overload situation lets check
+ TyTy::FnType *fntype;
+ bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
+ expr.get_mappings ().get_hirid (), &fntype);
+ if (is_op_overload)
+ {
+ auto lang_item_type
+ = Analysis::RustLangItem::NegationOperatorToLangItem (op);
+ translated
+ = resolve_operator_overload (lang_item_type, expr, negated_expr,
+ nullptr, expr.get_expr ().get (), nullptr);
+ return;
+ }
+
+ translated
+ = ctx->get_backend ()->negation_expression (op, negated_expr, location);
+}
+
+tree
+CompileExpr::compile_dyn_dispatch_call (const TyTy::DynamicObjectType *dyn,
+ TyTy::BaseType *receiver,
+ TyTy::FnType *fntype, tree receiver_ref,
+ std::vector<HIR::Expr *> &arguments,
+ Location expr_locus)
+{
+ size_t offs = 0;
+ const Resolver::TraitItemReference *ref = nullptr;
+ for (auto &bound : dyn->get_object_items ())
+ {
+ const Resolver::TraitItemReference *item = bound.first;
+ auto t = item->get_tyty ();
+ rust_assert (t->get_kind () == TyTy::TypeKind::FNDEF);
+ auto ft = static_cast<TyTy::FnType *> (t);
+
+ if (ft->get_id () == fntype->get_id ())
+ {
+ ref = item;
+ break;
+ }
+ offs++;
+ }
+
+ if (ref == nullptr)
+ return ctx->get_backend ()->error_expression ();
+
+ // get any indirection sorted out
+ if (receiver->get_kind () == TyTy::TypeKind::REF)
+ {
+ TyTy::ReferenceType *r = static_cast<TyTy::ReferenceType *> (receiver);
+ auto indirect_ty = r->get_base ();
+ tree indrect_compiled_tyty
+ = TyTyResolveCompile::compile (ctx, indirect_ty);
+
+ tree indirect
+ = ctx->get_backend ()->indirect_expression (indrect_compiled_tyty,
+ receiver_ref, true,
+ expr_locus);
+ receiver_ref = indirect;
+ }
+
+ // access the offs + 1 for the fnptr and offs=0 for the reciever obj
+ tree self_argument
+ = ctx->get_backend ()->struct_field_expression (receiver_ref, 0,
+ expr_locus);
+
+ // access the vtable for the fn
+ tree fn_vtable_access
+ = ctx->get_backend ()->struct_field_expression (receiver_ref, offs + 1,
+ expr_locus);
+
+ // cast it to the correct fntype
+ tree expected_fntype = TyTyResolveCompile::compile (ctx, fntype, true);
+ tree fn_convert_expr
+ = ctx->get_backend ()->convert_expression (expected_fntype,
+ fn_vtable_access, expr_locus);
+
+ fncontext fnctx = ctx->peek_fn ();
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ bool is_address_taken = false;
+ tree ret_var_stmt = NULL_TREE;
+ Bvariable *fn_convert_expr_tmp
+ = ctx->get_backend ()->temporary_variable (fnctx.fndecl, enclosing_scope,
+ expected_fntype, fn_convert_expr,
+ is_address_taken, expr_locus,
+ &ret_var_stmt);
+ ctx->add_statement (ret_var_stmt);
+
+ std::vector<tree> args;
+ args.push_back (self_argument);
+ for (auto &argument : arguments)
+ {
+ tree compiled_expr = CompileExpr::Compile (argument, ctx);
+ args.push_back (compiled_expr);
+ }
+
+ tree fn_expr
+ = ctx->get_backend ()->var_expression (fn_convert_expr_tmp, expr_locus);
+
+ return ctx->get_backend ()->call_expression (fnctx.fndecl, fn_expr, args,
+ nullptr, expr_locus);
+}
+
+tree
+CompileExpr::resolve_method_address (TyTy::FnType *fntype, HirId ref,
+ TyTy::BaseType *receiver,
+ HIR::PathIdentSegment &segment,
+ Analysis::NodeMapping expr_mappings,
+ Location expr_locus)
+{
+ // lookup compiled functions since it may have already been compiled
+ tree fn = NULL_TREE;
+ if (ctx->lookup_function_decl (fntype->get_ty_ref (), &fn))
+ {
+ return ctx->get_backend ()->function_code_expression (fn, expr_locus);
+ }
+
+ // Now we can try and resolve the address since this might be a forward
+ // declared function, generic function which has not be compiled yet or
+ // its an not yet trait bound function
+ HIR::ImplItem *resolved_item
+ = ctx->get_mappings ()->lookup_hir_implitem (expr_mappings.get_crate_num (),
+ ref, nullptr);
+ if (resolved_item != nullptr)
+ {
+ if (!fntype->has_subsititions_defined ())
+ return CompileInherentImplItem::Compile (receiver, resolved_item, ctx,
+ true);
+
+ return CompileInherentImplItem::Compile (receiver, resolved_item, ctx,
+ true, fntype);
+ }
+
+ // it might be resolved to a trait item
+ HIR::TraitItem *trait_item = ctx->get_mappings ()->lookup_hir_trait_item (
+ expr_mappings.get_crate_num (), ref);
+ HIR::Trait *trait = ctx->get_mappings ()->lookup_trait_item_mapping (
+ trait_item->get_mappings ().get_hirid ());
+
+ Resolver::TraitReference *trait_ref
+ = &Resolver::TraitReference::error_node ();
+ bool ok = ctx->get_tyctx ()->lookup_trait_reference (
+ trait->get_mappings ().get_defid (), &trait_ref);
+ rust_assert (ok);
+
+ // the type resolver can only resolve type bounds to their trait
+ // item so its up to us to figure out if this path should resolve
+ // to an trait-impl-block-item or if it can be defaulted to the
+ // trait-impl-item's definition
+
+ auto root = receiver->get_root ();
+ std::vector<Resolver::PathProbeCandidate> candidates
+ = Resolver::PathProbeType::Probe (root, segment, true, false, true);
+
+ if (candidates.size () == 0)
+ {
+ // this means we are defaulting back to the trait_item if
+ // possible
+ Resolver::TraitItemReference *trait_item_ref = nullptr;
+ bool ok = trait_ref->lookup_hir_trait_item (*trait_item, &trait_item_ref);
+ rust_assert (ok); // found
+ rust_assert (trait_item_ref->is_optional ()); // has definition
+
+ // FIXME Optional means it has a definition and an associated
+ // block which can be a default implementation, if it does not
+ // contain an implementation we should actually return
+ // error_mark_node
+
+ return CompileTraitItem::Compile (receiver,
+ trait_item_ref->get_hir_trait_item (),
+ ctx, fntype, true, expr_locus);
+ }
+ else
+ {
+ std::vector<Resolver::Adjustment> adjustments;
+ Resolver::PathProbeCandidate *candidate
+ = Resolver::MethodResolution::Select (candidates, root, adjustments);
+
+ // FIXME this will be a case to return error_mark_node, there is
+ // an error scenario where a Trait Foo has a method Bar, but this
+ // receiver does not implement this trait or has an incompatible
+ // implementation and we should just return error_mark_node
+ rust_assert (candidate != nullptr);
+ rust_assert (candidate->is_impl_candidate ());
+
+ HIR::ImplItem *impl_item = candidate->item.impl.impl_item;
+ if (!fntype->has_subsititions_defined ())
+ return CompileInherentImplItem::Compile (receiver, impl_item, ctx,
+ true);
+
+ return CompileInherentImplItem::Compile (receiver, impl_item, ctx, true,
+ fntype);
+ }
+}
+
+tree
+CompileExpr::resolve_operator_overload (
+ Analysis::RustLangItem::ItemType lang_item_type, HIR::OperatorExpr &expr,
+ tree lhs, tree rhs, HIR::Expr *lhs_expr, HIR::Expr *rhs_expr)
+{
+ TyTy::FnType *fntype;
+ bool is_op_overload = ctx->get_tyctx ()->lookup_operator_overload (
+ expr.get_mappings ().get_hirid (), &fntype);
+ rust_assert (is_op_overload);
+
+ // lookup the resolved name
+ NodeId resolved_node_id = UNKNOWN_NODEID;
+ bool ok = ctx->get_resolver ()->lookup_resolved_name (
+ expr.get_mappings ().get_nodeid (), &resolved_node_id);
+ rust_assert (ok);
+
+ // reverse lookup
+ HirId ref;
+ ok = ctx->get_mappings ()->lookup_node_to_hir (
+ expr.get_mappings ().get_crate_num (), resolved_node_id, &ref);
+ rust_assert (ok);
+
+ TyTy::BaseType *receiver = nullptr;
+ ok = ctx->get_tyctx ()->lookup_receiver (expr.get_mappings ().get_hirid (),
+ &receiver);
+ rust_assert (ok);
+
+ bool is_dyn_dispatch
+ = receiver->get_root ()->get_kind () == TyTy::TypeKind::DYNAMIC;
+ bool is_generic_receiver = receiver->get_kind () == TyTy::TypeKind::PARAM;
+ if (is_generic_receiver)
+ {
+ TyTy::ParamType *p = static_cast<TyTy::ParamType *> (receiver);
+ receiver = p->resolve ();
+ }
+
+ if (is_dyn_dispatch)
+ {
+ const TyTy::DynamicObjectType *dyn
+ = static_cast<const TyTy::DynamicObjectType *> (receiver->get_root ());
+
+ std::vector<HIR::Expr *> arguments;
+ if (rhs_expr != nullptr) // can be null for negation_expr (unary ones)
+ arguments.push_back (rhs_expr);
+
+ return compile_dyn_dispatch_call (dyn, receiver, fntype, lhs, arguments,
+ expr.get_locus ());
+ }
+
+ // lookup compiled functions since it may have already been compiled
+ HIR::PathIdentSegment segment_name (
+ Analysis::RustLangItem::ToString (lang_item_type));
+ tree fn_expr
+ = resolve_method_address (fntype, ref, receiver, segment_name,
+ expr.get_mappings (), expr.get_locus ());
+
+ // lookup the autoderef mappings
+ std::vector<Resolver::Adjustment> *adjustments = nullptr;
+ ok = ctx->get_tyctx ()->lookup_autoderef_mappings (
+ expr.get_mappings ().get_hirid (), &adjustments);
+ rust_assert (ok);
+
+ // FIXME refactor this out
+ tree self = lhs;
+ for (auto &adjustment : *adjustments)
+ {
+ switch (adjustment.get_type ())
+ {
+ case Resolver::Adjustment::AdjustmentType::IMM_REF:
+ case Resolver::Adjustment::AdjustmentType::MUT_REF:
+ self
+ = ctx->get_backend ()->address_expression (self,
+ lhs_expr->get_locus ());
+ break;
+
+ case Resolver::Adjustment::AdjustmentType::DEREF_REF:
+ tree expected_type
+ = TyTyResolveCompile::compile (ctx, adjustment.get_expected ());
+ self
+ = ctx->get_backend ()->indirect_expression (expected_type, self,
+ true, /* known_valid*/
+ lhs_expr->get_locus ());
+ break;
+ }
+ }
+
+ std::vector<tree> args;
+ args.push_back (self); // adjusted self
+ if (rhs != nullptr) // can be null for negation_expr (unary ones)
+ args.push_back (rhs);
+
+ auto fncontext = ctx->peek_fn ();
+ return ctx->get_backend ()->call_expression (fncontext.fndecl, fn_expr, args,
+ nullptr, expr.get_locus ());
+}
+
+} // namespace Compile
+} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index f43db50..2bf969b 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -33,7 +33,7 @@ class CompileExpr : public HIRCompileBase
using Rust::Compile::HIRCompileBase::visit;
public:
- static Bexpression *Compile (HIR::Expr *expr, Context *ctx)
+ static tree Compile (HIR::Expr *expr, Context *ctx)
{
CompileExpr compiler (ctx);
expr->accept_vis (compiler);
@@ -45,7 +45,7 @@ public:
HIR::Expr *tuple_expr = expr.get_tuple_expr ().get ();
TupleIndex index = expr.get_tuple_index ();
- Bexpression *receiver_ref = CompileExpr::Compile (tuple_expr, ctx);
+ tree receiver_ref = CompileExpr::Compile (tuple_expr, ctx);
TyTy::BaseType *tuple_expr_ty = nullptr;
bool ok = ctx->get_tyctx ()->lookup_type (
@@ -58,9 +58,9 @@ public:
TyTy::ReferenceType *r
= static_cast<TyTy::ReferenceType *> (tuple_expr_ty);
TyTy::BaseType *tuple_type = r->get_base ();
- Btype *tuple_tyty = TyTyResolveCompile::compile (ctx, tuple_type);
+ tree tuple_tyty = TyTyResolveCompile::compile (ctx, tuple_type);
- Bexpression *indirect
+ tree indirect
= ctx->get_backend ()->indirect_expression (tuple_tyty, receiver_ref,
true, expr.get_locus ());
receiver_ref = indirect;
@@ -88,11 +88,11 @@ public:
return;
}
- Btype *tuple_type = TyTyResolveCompile::compile (ctx, tyty);
+ tree tuple_type = TyTyResolveCompile::compile (ctx, tyty);
rust_assert (tuple_type != nullptr);
// this assumes all fields are in order from type resolution
- std::vector<Bexpression *> vals;
+ std::vector<tree> vals;
for (auto &elem : expr.get_tuple_elems ())
{
auto e = CompileExpr::Compile (elem.get (), ctx);
@@ -108,10 +108,10 @@ public:
{
auto fncontext = ctx->peek_fn ();
- std::vector<Bexpression *> retstmts;
+ std::vector<tree> retstmts;
if (expr.has_return_expr ())
{
- Bexpression *compiled_expr
+ tree compiled_expr
= CompileExpr::Compile (expr.return_expr.get (), ctx);
rust_assert (compiled_expr != nullptr);
@@ -204,7 +204,7 @@ public:
gcc_unreachable ();
}
- Bfunction *fn = nullptr;
+ tree fn = NULL_TREE;
Bvariable *var = nullptr;
if (ctx->lookup_const_decl (ref, &translated))
{
@@ -259,7 +259,7 @@ public:
return;
}
- Btype *type = TyTyResolveCompile::compile (ctx, tyty);
+ tree type = TyTyResolveCompile::compile (ctx, tyty);
translated
= ctx->get_backend ()->integer_constant_expression (type, ival);
}
@@ -285,7 +285,7 @@ public:
return;
}
- Btype *type = TyTyResolveCompile::compile (ctx, tyty);
+ tree type = TyTyResolveCompile::compile (ctx, tyty);
translated
= ctx->get_backend ()->float_constant_expression (type, fval);
}
@@ -330,21 +330,19 @@ public:
auto array_tyty = static_cast<TyTy::ArrayType *> (base_tyty);
std::string value_str = expr.get_literal ()->as_string ();
- std::vector<Bexpression *> vals;
+ std::vector<tree> vals;
std::vector<unsigned long> indexes;
for (size_t i = 0; i < value_str.size (); i++)
{
char b = value_str.at (i);
- Bexpression *bb
- = ctx->get_backend ()->char_constant_expression (b);
+ tree bb = ctx->get_backend ()->char_constant_expression (b);
vals.push_back (bb);
indexes.push_back (i);
}
- Btype *array_type = TyTyResolveCompile::compile (ctx, array_tyty);
- Bexpression *constructed
- = ctx->get_backend ()->array_constructor_expression (
- array_type, indexes, vals, expr.get_locus ());
+ tree array_type = TyTyResolveCompile::compile (ctx, array_tyty);
+ tree constructed = ctx->get_backend ()->array_constructor_expression (
+ array_type, indexes, vals, expr.get_locus ());
translated
= ctx->get_backend ()->address_expression (constructed,
@@ -381,17 +379,19 @@ public:
rvalue = coercion_site (rvalue, actual, expected, expr.get_locus ());
- Bstatement *assignment
+ tree assignment
= ctx->get_backend ()->assignment_statement (fn.fndecl, lvalue, rvalue,
expr.get_locus ());
ctx->add_statement (assignment);
}
+ void visit (HIR::CompoundAssignmentExpr &expr) override;
+
void visit (HIR::ArrayIndexExpr &expr) override
{
- Bexpression *array = CompileExpr::Compile (expr.get_array_expr (), ctx);
- Bexpression *index = CompileExpr::Compile (expr.get_index_expr (), ctx);
+ tree array = CompileExpr::Compile (expr.get_array_expr (), ctx);
+ tree index = CompileExpr::Compile (expr.get_index_expr (), ctx);
translated
= ctx->get_backend ()->array_index_expression (array, index,
expr.get_locus ());
@@ -412,7 +412,7 @@ public:
TyTy::ArrayType *array_tyty = static_cast<TyTy::ArrayType *> (tyty);
capacity_expr = array_tyty->get_capacity ();
- Btype *array_type = TyTyResolveCompile::compile (ctx, array_tyty);
+ tree array_type = TyTyResolveCompile::compile (ctx, array_tyty);
rust_assert (array_type != nullptr);
expr.get_internal_elements ()->accept_vis (*this);
@@ -430,14 +430,14 @@ public:
{
for (auto &elem : elems.get_values ())
{
- Bexpression *translated_expr = CompileExpr::Compile (elem.get (), ctx);
+ tree translated_expr = CompileExpr::Compile (elem.get (), ctx);
constructor.push_back (translated_expr);
}
}
void visit (HIR::ArrayElemsCopied &elems) override
{
- Bexpression *translated_expr
+ tree translated_expr
= CompileExpr::Compile (elems.get_elem_to_copy (), ctx);
size_t capacity;
@@ -448,17 +448,7 @@ public:
constructor.push_back (translated_expr);
}
- void visit (HIR::ArithmeticOrLogicalExpr &expr) override
- {
- auto op = expr.get_expr_type ();
- auto lhs = CompileExpr::Compile (expr.get_lhs (), ctx);
- auto rhs = CompileExpr::Compile (expr.get_rhs (), ctx);
- auto location = expr.get_locus ();
-
- translated
- = ctx->get_backend ()->arithmetic_or_logical_expression (op, lhs, rhs,
- location);
- }
+ void visit (HIR::ArithmeticOrLogicalExpr &expr) override;
void visit (HIR::ComparisonExpr &expr) override
{
@@ -482,15 +472,7 @@ public:
= ctx->get_backend ()->lazy_boolean_expression (op, lhs, rhs, location);
}
- void visit (HIR::NegationExpr &expr) override
- {
- auto op = expr.get_expr_type ();
- auto negated_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
- auto location = expr.get_locus ();
-
- translated
- = ctx->get_backend ()->negation_expression (op, negated_expr, location);
- }
+ void visit (HIR::NegationExpr &expr) override;
void visit (HIR::TypeCastExpr &expr) override
{
@@ -532,11 +514,11 @@ public:
if (needs_temp)
{
fncontext fnctx = ctx->peek_fn ();
- Bblock *enclosing_scope = ctx->peek_enclosing_scope ();
- Btype *block_type = TyTyResolveCompile::compile (ctx, if_type);
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree block_type = TyTyResolveCompile::compile (ctx, if_type);
bool is_address_taken = false;
- Bstatement *ret_var_stmt = nullptr;
+ tree ret_var_stmt = nullptr;
tmp = ctx->get_backend ()->temporary_variable (
fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
expr.get_locus (), &ret_var_stmt);
@@ -569,11 +551,11 @@ public:
if (needs_temp)
{
fncontext fnctx = ctx->peek_fn ();
- Bblock *enclosing_scope = ctx->peek_enclosing_scope ();
- Btype *block_type = TyTyResolveCompile::compile (ctx, if_type);
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree block_type = TyTyResolveCompile::compile (ctx, if_type);
bool is_address_taken = false;
- Bstatement *ret_var_stmt = nullptr;
+ tree ret_var_stmt = nullptr;
tmp = ctx->get_backend ()->temporary_variable (
fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
expr.get_locus (), &ret_var_stmt);
@@ -605,11 +587,11 @@ public:
if (needs_temp)
{
fncontext fnctx = ctx->peek_fn ();
- Bblock *enclosing_scope = ctx->peek_enclosing_scope ();
- Btype *block_type = TyTyResolveCompile::compile (ctx, block_tyty);
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree block_type = TyTyResolveCompile::compile (ctx, block_tyty);
bool is_address_taken = false;
- Bstatement *ret_var_stmt = nullptr;
+ tree ret_var_stmt = nullptr;
tmp = ctx->get_backend ()->temporary_variable (
fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
expr.get_locus (), &ret_var_stmt);
@@ -656,15 +638,15 @@ public:
return;
}
- Btype *type = TyTyResolveCompile::compile (ctx, tyty);
+ tree type = TyTyResolveCompile::compile (ctx, tyty);
rust_assert (type != nullptr);
// this assumes all fields are in order from type resolution and if a base
// struct was specified those fields are filed via accesors
- std::vector<Bexpression *> vals;
+ std::vector<tree> vals;
for (auto &field : struct_expr.get_fields ())
{
- Bexpression *expr = CompileStructExprField::Compile (field.get (), ctx);
+ tree expr = CompileStructExprField::Compile (field.get (), ctx);
vals.push_back (expr);
}
@@ -681,7 +663,7 @@ public:
void visit (HIR::FieldAccessExpr &expr) override
{
- Bexpression *receiver_ref
+ tree receiver_ref
= CompileExpr::Compile (expr.get_receiver_expr ().get (), ctx);
// resolve the receiver back to ADT type
@@ -721,8 +703,8 @@ public:
&field_index);
rust_assert (ok);
- Btype *adt_tyty = TyTyResolveCompile::compile (ctx, adt);
- Bexpression *indirect
+ tree adt_tyty = TyTyResolveCompile::compile (ctx, adt);
+ tree indirect
= ctx->get_backend ()->indirect_expression (adt_tyty, receiver_ref,
true, expr.get_locus ());
receiver_ref = indirect;
@@ -758,11 +740,11 @@ public:
bool needs_temp = !block_tyty->is_unit ();
if (needs_temp)
{
- Bblock *enclosing_scope = ctx->peek_enclosing_scope ();
- Btype *block_type = TyTyResolveCompile::compile (ctx, block_tyty);
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree block_type = TyTyResolveCompile::compile (ctx, block_tyty);
bool is_address_taken = false;
- Bstatement *ret_var_stmt = nullptr;
+ tree ret_var_stmt = NULL_TREE;
tmp = ctx->get_backend ()->temporary_variable (
fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
expr.get_locus (), &ret_var_stmt);
@@ -773,29 +755,29 @@ public:
if (expr.has_loop_label ())
{
HIR::LoopLabel &loop_label = expr.get_loop_label ();
- Blabel *label
+ tree label
= ctx->get_backend ()->label (fnctx.fndecl,
loop_label.get_lifetime ().get_name (),
loop_label.get_locus ());
- Bstatement *label_decl
+ tree label_decl
= ctx->get_backend ()->label_definition_statement (label);
ctx->add_statement (label_decl);
ctx->insert_label_decl (
loop_label.get_lifetime ().get_mappings ().get_hirid (), label);
}
- Blabel *loop_begin_label
+ tree loop_begin_label
= ctx->get_backend ()->label (fnctx.fndecl, "", expr.get_locus ());
- Bstatement *loop_begin_label_decl
+ tree loop_begin_label_decl
= ctx->get_backend ()->label_definition_statement (loop_begin_label);
ctx->add_statement (loop_begin_label_decl);
ctx->push_loop_begin_label (loop_begin_label);
- Bblock *code_block
+ tree code_block
= CompileBlock::compile (expr.get_loop_block ().get (), ctx, nullptr);
- Bexpression *loop_expr
+ tree loop_expr
= ctx->get_backend ()->loop_expression (code_block, expr.get_locus ());
- Bstatement *loop_stmt
+ tree loop_stmt
= ctx->get_backend ()->expression_statement (fnctx.fndecl, loop_expr);
ctx->add_statement (loop_stmt);
@@ -814,11 +796,11 @@ public:
if (expr.has_loop_label ())
{
HIR::LoopLabel &loop_label = expr.get_loop_label ();
- Blabel *label
+ tree label
= ctx->get_backend ()->label (fnctx.fndecl,
loop_label.get_lifetime ().get_name (),
loop_label.get_locus ());
- Bstatement *label_decl
+ tree label_decl
= ctx->get_backend ()->label_definition_statement (label);
ctx->add_statement (label_decl);
ctx->insert_label_decl (
@@ -829,39 +811,38 @@ public:
Location start_location = expr.get_loop_block ()->get_locus ();
Location end_location = expr.get_loop_block ()->get_locus (); // FIXME
- Bblock *enclosing_scope = ctx->peek_enclosing_scope ();
- Bblock *loop_block
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree loop_block
= ctx->get_backend ()->block (fnctx.fndecl, enclosing_scope, locals,
start_location, end_location);
ctx->push_block (loop_block);
- Blabel *loop_begin_label
+ tree loop_begin_label
= ctx->get_backend ()->label (fnctx.fndecl, "", expr.get_locus ());
- Bstatement *loop_begin_label_decl
+ tree loop_begin_label_decl
= ctx->get_backend ()->label_definition_statement (loop_begin_label);
ctx->add_statement (loop_begin_label_decl);
ctx->push_loop_begin_label (loop_begin_label);
- Bexpression *condition
+ tree condition
= CompileExpr::Compile (expr.get_predicate_expr ().get (), ctx);
- Bexpression *exit_expr
+ tree exit_expr
= ctx->get_backend ()->exit_expression (condition, expr.get_locus ());
- Bstatement *break_stmt
+ tree break_stmt
= ctx->get_backend ()->expression_statement (fnctx.fndecl, exit_expr);
ctx->add_statement (break_stmt);
- Bblock *code_block
+ tree code_block
= CompileBlock::compile (expr.get_loop_block ().get (), ctx, nullptr);
- Bstatement *code_block_stmt
- = ctx->get_backend ()->block_statement (code_block);
+ tree code_block_stmt = ctx->get_backend ()->block_statement (code_block);
ctx->add_statement (code_block_stmt);
ctx->pop_loop_begin_label ();
ctx->pop_block ();
- Bexpression *loop_expr
+ tree loop_expr
= ctx->get_backend ()->loop_expression (loop_block, expr.get_locus ());
- Bstatement *loop_stmt
+ tree loop_stmt
= ctx->get_backend ()->expression_statement (fnctx.fndecl, loop_expr);
ctx->add_statement (loop_stmt);
}
@@ -871,14 +852,14 @@ public:
fncontext fnctx = ctx->peek_fn ();
if (expr.has_break_expr ())
{
- Bexpression *compiled_expr
+ tree compiled_expr
= CompileExpr::Compile (expr.get_expr ().get (), ctx);
Bvariable *loop_result_holder = ctx->peek_loop_context ();
- Bexpression *result_reference = ctx->get_backend ()->var_expression (
+ tree result_reference = ctx->get_backend ()->var_expression (
loop_result_holder, expr.get_expr ()->get_locus ());
- Bstatement *assignment = ctx->get_backend ()->assignment_statement (
+ tree assignment = ctx->get_backend ()->assignment_statement (
fnctx.fndecl, result_reference, compiled_expr, expr.get_locus ());
ctx->add_statement (assignment);
}
@@ -906,7 +887,7 @@ public:
return;
}
- Blabel *label = nullptr;
+ tree label = NULL_TREE;
if (!ctx->lookup_label_decl (ref, &label))
{
rust_error_at (expr.get_label ().get_locus (),
@@ -914,16 +895,16 @@ public:
return;
}
- Bstatement *goto_label
+ tree goto_label
= ctx->get_backend ()->goto_statement (label, expr.get_locus ());
ctx->add_statement (goto_label);
}
else
{
- Bexpression *exit_expr = ctx->get_backend ()->exit_expression (
+ tree exit_expr = ctx->get_backend ()->exit_expression (
ctx->get_backend ()->boolean_constant_expression (true),
expr.get_locus ());
- Bstatement *break_stmt
+ tree break_stmt
= ctx->get_backend ()->expression_statement (fnctx.fndecl, exit_expr);
ctx->add_statement (break_stmt);
}
@@ -931,7 +912,7 @@ public:
void visit (HIR::ContinueExpr &expr) override
{
- Blabel *label = ctx->peek_loop_begin_label ();
+ tree label = ctx->peek_loop_begin_label ();
if (expr.has_label ())
{
NodeId resolved_node_id = UNKNOWN_NODEID;
@@ -963,15 +944,14 @@ public:
}
}
- Bstatement *goto_label
+ tree goto_label
= ctx->get_backend ()->goto_statement (label, expr.get_locus ());
ctx->add_statement (goto_label);
}
void visit (HIR::BorrowExpr &expr) override
{
- Bexpression *main_expr
- = CompileExpr::Compile (expr.get_expr ().get (), ctx);
+ tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
translated
= ctx->get_backend ()->address_expression (main_expr, expr.get_locus ());
@@ -979,8 +959,7 @@ public:
void visit (HIR::DereferenceExpr &expr) override
{
- Bexpression *main_expr
- = CompileExpr::Compile (expr.get_expr ().get (), ctx);
+ tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
TyTy::BaseType *tyty = nullptr;
if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
@@ -991,7 +970,7 @@ public:
return;
}
- Btype *expected_type = TyTyResolveCompile::compile (ctx, tyty);
+ tree expected_type = TyTyResolveCompile::compile (ctx, tyty);
bool known_valid = true;
translated
= ctx->get_backend ()->indirect_expression (expected_type, main_expr,
@@ -999,14 +978,32 @@ public:
expr.get_locus ());
}
+protected:
+ tree compile_dyn_dispatch_call (const TyTy::DynamicObjectType *dyn,
+ TyTy::BaseType *receiver,
+ TyTy::FnType *fntype, tree receiver_ref,
+ std::vector<HIR::Expr *> &arguments,
+ Location expr_locus);
+
+ tree resolve_method_address (TyTy::FnType *fntype, HirId ref,
+ TyTy::BaseType *receiver,
+ HIR::PathIdentSegment &segment,
+ Analysis::NodeMapping expr_mappings,
+ Location expr_locus);
+
+ tree
+ resolve_operator_overload (Analysis::RustLangItem::ItemType lang_item_type,
+ HIR::OperatorExpr &expr, tree lhs, tree rhs,
+ HIR::Expr *lhs_expr, HIR::Expr *rhs_expr);
+
private:
CompileExpr (Context *ctx)
: HIRCompileBase (ctx), translated (nullptr), capacity_expr (nullptr)
{}
- Bexpression *translated;
- Bexpression *capacity_expr;
- std::vector<Bexpression *> constructor;
+ tree translated;
+ tree capacity_expr;
+ std::vector<tree> constructor;
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h
index 6e5a3fd..aa73509 100644
--- a/gcc/rust/backend/rust-compile-extern.h
+++ b/gcc/rust/backend/rust-compile-extern.h
@@ -55,7 +55,7 @@ public:
// FIXME this is assuming C ABI
std::string asm_name = name;
- Btype *type = TyTyResolveCompile::compile (ctx, resolved_type);
+ tree type = TyTyResolveCompile::compile (ctx, resolved_type);
bool is_external = true;
bool is_hidden = false;
bool in_unique_section = false;
@@ -99,14 +99,14 @@ public:
// items can be forward compiled which means we may not need to invoke this
// code. We might also have already compiled this generic function as well.
- Bfunction *lookup = nullptr;
+ tree lookup = NULL_TREE;
if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
fntype->get_id (), fntype))
{
// has this been added to the list then it must be finished
if (ctx->function_completed (lookup))
{
- Bfunction *dummy = nullptr;
+ tree dummy = NULL_TREE;
if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
ctx->insert_function_decl (fntype, lookup);
@@ -123,12 +123,12 @@ public:
if (fntype->get_abi () == ABI::INTRINSIC)
{
Intrinsics compile (ctx);
- Bfunction *fndecl = compile.compile (fntype);
+ tree fndecl = compile.compile (fntype);
ctx->insert_function_decl (fntype, fndecl);
return;
}
- ::Btype *compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
+ tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
compiled_fn_type
= ctx->get_backend ()->specify_abi_attribute (compiled_fn_type,
fntype->get_abi ());
@@ -139,7 +139,7 @@ public:
std::string ir_symbol_name = function.get_item_name ();
std::string asm_name = function.get_item_name ();
- Bfunction *fndecl
+ tree fndecl
= ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
asm_name, flags, function.get_locus ());
ctx->insert_function_decl (fntype, fndecl);
diff --git a/gcc/rust/backend/rust-compile-fnparam.h b/gcc/rust/backend/rust-compile-fnparam.h
index b246948..629f0f5 100644
--- a/gcc/rust/backend/rust-compile-fnparam.h
+++ b/gcc/rust/backend/rust-compile-fnparam.h
@@ -29,8 +29,8 @@ class CompileFnParam : public HIRCompileBase
using Rust::Compile::HIRCompileBase::visit;
public:
- static Bvariable *compile (Context *ctx, Bfunction *fndecl,
- HIR::FunctionParam *param, Btype *decl_type,
+ static Bvariable *compile (Context *ctx, tree fndecl,
+ HIR::FunctionParam *param, tree decl_type,
Location locus)
{
CompileFnParam compiler (ctx, fndecl, decl_type, locus);
@@ -51,14 +51,13 @@ public:
}
private:
- CompileFnParam (Context *ctx, ::Bfunction *fndecl, ::Btype *decl_type,
- Location locus)
+ CompileFnParam (Context *ctx, tree fndecl, tree decl_type, Location locus)
: HIRCompileBase (ctx), fndecl (fndecl), decl_type (decl_type),
locus (locus), translated (nullptr)
{}
- ::Bfunction *fndecl;
- ::Btype *decl_type;
+ tree fndecl;
+ tree decl_type;
Location locus;
::Bvariable *translated;
};
@@ -66,9 +65,8 @@ private:
class CompileSelfParam : public HIRCompileBase
{
public:
- static Bvariable *compile (Context *ctx, Bfunction *fndecl,
- HIR::SelfParam &self, Btype *decl_type,
- Location locus)
+ static Bvariable *compile (Context *ctx, tree fndecl, HIR::SelfParam &self,
+ tree decl_type, Location locus)
{
bool is_immutable
= self.get_self_kind () == HIR::SelfParam::ImplicitSelfKind::IMM
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h
index 05c7910..7b41226 100644
--- a/gcc/rust/backend/rust-compile-implitem.h
+++ b/gcc/rust/backend/rust-compile-implitem.h
@@ -34,11 +34,11 @@ class CompileInherentImplItem : public HIRCompileBase
using Rust::Compile::HIRCompileBase::visit;
public:
- static Bexpression *Compile (const TyTy::BaseType *self, HIR::ImplItem *item,
- Context *ctx, bool compile_fns,
- TyTy::BaseType *concrete = nullptr,
- bool is_query_mode = false,
- Location ref_locus = Location ())
+ static tree Compile (const TyTy::BaseType *self, HIR::ImplItem *item,
+ Context *ctx, bool compile_fns,
+ TyTy::BaseType *concrete = nullptr,
+ bool is_query_mode = false,
+ Location ref_locus = Location ())
{
CompileInherentImplItem compiler (self, ctx, compile_fns, concrete,
ref_locus);
@@ -60,8 +60,8 @@ public:
&resolved_type);
rust_assert (ok);
- ::Btype *type = TyTyResolveCompile::compile (ctx, resolved_type);
- Bexpression *value = CompileExpr::Compile (constant.get_expr (), ctx);
+ tree type = TyTyResolveCompile::compile (ctx, resolved_type);
+ tree value = CompileExpr::Compile (constant.get_expr (), ctx);
const Resolver::CanonicalPath *canonical_path = nullptr;
ok = ctx->get_mappings ()->lookup_canonical_path (
@@ -70,7 +70,7 @@ public:
rust_assert (ok);
std::string ident = canonical_path->get ();
- Bexpression *const_expr = ctx->get_backend ()->named_constant_expression (
+ tree const_expr = ctx->get_backend ()->named_constant_expression (
type, constant.get_identifier (), value, constant.get_locus ());
ctx->push_const (const_expr);
@@ -110,14 +110,14 @@ public:
// items can be forward compiled which means we may not need to invoke this
// code. We might also have already compiled this generic function as well.
- Bfunction *lookup = nullptr;
+ tree lookup = NULL_TREE;
if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
fntype->get_id (), fntype))
{
// has this been added to the list then it must be finished
if (ctx->function_completed (lookup))
{
- Bfunction *dummy = nullptr;
+ tree dummy = NULL_TREE;
if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
{
ctx->insert_function_decl (fntype, lookup);
@@ -136,7 +136,7 @@ public:
}
// convert to the actual function type
- ::Btype *compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
+ tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
unsigned int flags = 0;
@@ -156,7 +156,7 @@ public:
std::string asm_name
= ctx->mangle_impl_item (self, fntype, function.get_function_name ());
- Bfunction *fndecl
+ tree fndecl
= ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
asm_name, flags, function.get_locus ());
ctx->insert_function_decl (fntype, fndecl);
@@ -178,7 +178,7 @@ public:
return;
}
- Btype *self_type = TyTyResolveCompile::compile (ctx, self_tyty_lookup);
+ tree self_type = TyTyResolveCompile::compile (ctx, self_tyty_lookup);
if (self_type == nullptr)
{
rust_error_at (function.get_self_param ().get_locus (),
@@ -262,12 +262,12 @@ public:
ok = compile_locals_for_block (*rib, fndecl, locals);
rust_assert (ok);
- Bblock *enclosing_scope = NULL;
+ tree enclosing_scope = NULL_TREE;
HIR::BlockExpr *function_body = function.get_definition ().get ();
Location start_location = function_body->get_locus ();
Location end_location = function_body->get_closing_locus ();
- Bblock *code_block
+ tree code_block
= ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
start_location, end_location);
ctx->push_block (code_block);
@@ -275,10 +275,10 @@ public:
Bvariable *return_address = nullptr;
if (function.has_function_return_type ())
{
- Btype *return_type = TyTyResolveCompile::compile (ctx, tyret);
+ tree return_type = TyTyResolveCompile::compile (ctx, tyret);
bool address_is_taken = false;
- Bstatement *ret_var_stmt = nullptr;
+ tree ret_var_stmt = NULL_TREE;
return_address = ctx->get_backend ()->temporary_variable (
fndecl, code_block, return_type, NULL, address_is_taken,
@@ -319,7 +319,7 @@ private:
const TyTy::BaseType *self;
bool compile_fns;
TyTy::BaseType *concrete;
- Bexpression *reference;
+ tree reference;
Location ref_locus;
};
@@ -328,10 +328,10 @@ class CompileTraitItem : public HIRCompileBase
using Rust::Compile::HIRCompileBase::visit;
public:
- static Bexpression *Compile (const TyTy::BaseType *self, HIR::TraitItem *item,
- Context *ctx, TyTy::BaseType *concrete,
- bool is_query_mode = false,
- Location ref_locus = Location ())
+ static tree Compile (const TyTy::BaseType *self, HIR::TraitItem *item,
+ Context *ctx, TyTy::BaseType *concrete,
+ bool is_query_mode = false,
+ Location ref_locus = Location ())
{
CompileTraitItem compiler (self, ctx, concrete, ref_locus);
item->accept_vis (compiler);
@@ -349,9 +349,8 @@ public:
rust_assert (concrete != nullptr);
TyTy::BaseType *resolved_type = concrete;
- ::Btype *type = TyTyResolveCompile::compile (ctx, resolved_type);
- Bexpression *value
- = CompileExpr::Compile (constant.get_expr ().get (), ctx);
+ tree type = TyTyResolveCompile::compile (ctx, resolved_type);
+ tree value = CompileExpr::Compile (constant.get_expr ().get (), ctx);
const Resolver::CanonicalPath *canonical_path = nullptr;
bool ok = ctx->get_mappings ()->lookup_canonical_path (
@@ -360,7 +359,7 @@ public:
rust_assert (ok);
std::string ident = canonical_path->get ();
- Bexpression *const_expr = ctx->get_backend ()->named_constant_expression (
+ tree const_expr = ctx->get_backend ()->named_constant_expression (
type, constant.get_name (), value, constant.get_locus ());
ctx->push_const (const_expr);
@@ -378,14 +377,14 @@ public:
// items can be forward compiled which means we may not need to invoke this
// code. We might also have already compiled this generic function as well.
- Bfunction *lookup = nullptr;
+ tree lookup = NULL_TREE;
if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
fntype->get_id (), fntype))
{
// has this been added to the list then it must be finished
if (ctx->function_completed (lookup))
{
- Bfunction *dummy = nullptr;
+ tree dummy = NULL_TREE;
if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
{
ctx->insert_function_decl (fntype, lookup);
@@ -404,7 +403,7 @@ public:
}
// convert to the actual function type
- ::Btype *compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
+ tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
HIR::TraitFunctionDecl &function = func.get_decl ();
unsigned int flags = 0;
@@ -418,7 +417,7 @@ public:
std::string fn_identifier = canonical_path->get ();
std::string asm_name = ctx->mangle_item (fntype, *canonical_path);
- Bfunction *fndecl
+ tree fndecl
= ctx->get_backend ()->function (compiled_fn_type, fn_identifier,
asm_name, flags, func.get_locus ());
ctx->insert_function_decl (fntype, fndecl);
@@ -440,7 +439,7 @@ public:
return;
}
- Btype *self_type = TyTyResolveCompile::compile (ctx, self_tyty_lookup);
+ tree self_type = TyTyResolveCompile::compile (ctx, self_tyty_lookup);
if (self_type == nullptr)
{
rust_error_at (function.get_self ().get_locus (),
@@ -523,12 +522,12 @@ public:
ok = compile_locals_for_block (*rib, fndecl, locals);
rust_assert (ok);
- Bblock *enclosing_scope = NULL;
+ tree enclosing_scope = NULL_TREE;
HIR::BlockExpr *function_body = func.get_block_expr ().get ();
Location start_location = function_body->get_locus ();
Location end_location = function_body->get_closing_locus ();
- Bblock *code_block
+ tree code_block
= ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
start_location, end_location);
ctx->push_block (code_block);
@@ -536,10 +535,10 @@ public:
Bvariable *return_address = nullptr;
if (function.has_return_type ())
{
- Btype *return_type = TyTyResolveCompile::compile (ctx, tyret);
+ tree return_type = TyTyResolveCompile::compile (ctx, tyret);
bool address_is_taken = false;
- Bstatement *ret_var_stmt = nullptr;
+ tree ret_var_stmt = NULL_TREE;
return_address = ctx->get_backend ()->temporary_variable (
fndecl, code_block, return_type, NULL, address_is_taken,
@@ -578,7 +577,7 @@ private:
const TyTy::BaseType *self;
TyTy::BaseType *concrete;
- Bexpression *reference;
+ tree reference;
Location ref_locus;
};
diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc
index 66d36e3..69626a9 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.cc
+++ b/gcc/rust/backend/rust-compile-intrinsic.cc
@@ -21,7 +21,7 @@ namespace Compile {
Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {}
-Bfunction *
+tree
Intrinsics::compile (TyTy::FnType *fntype)
{
rust_assert (fntype->get_abi () == ABI::INTRINSIC);
@@ -77,7 +77,7 @@ Intrinsics::compile (TyTy::FnType *fntype)
// };
// Some(cx.get_intrinsic(&llvm_name))
- Bfunction *builtin = ctx->get_backend ()->lookup_builtin_by_rust_name (
+ tree builtin = ctx->get_backend ()->lookup_builtin_by_rust_name (
fntype->get_identifier ());
if (builtin != nullptr)
return builtin;
diff --git a/gcc/rust/backend/rust-compile-intrinsic.h b/gcc/rust/backend/rust-compile-intrinsic.h
index 25e298a..2d44baa 100644
--- a/gcc/rust/backend/rust-compile-intrinsic.h
+++ b/gcc/rust/backend/rust-compile-intrinsic.h
@@ -27,7 +27,7 @@ class Intrinsics
public:
Intrinsics (Context *ctx);
- Bfunction *compile (TyTy::FnType *fntype);
+ tree compile (TyTy::FnType *fntype);
private:
Context *ctx;
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
index 6691c2a..5af9ab3 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -37,11 +37,10 @@ protected:
using Rust::Compile::HIRCompileBase::visit;
public:
- static Bexpression *compile (HIR::Item *item, Context *ctx,
- bool compile_fns = true,
- TyTy::BaseType *concrete = nullptr,
- bool is_query_mode = false,
- Location ref_locus = Location ())
+ static tree compile (HIR::Item *item, Context *ctx, bool compile_fns = true,
+ TyTy::BaseType *concrete = nullptr,
+ bool is_query_mode = false,
+ Location ref_locus = Location ())
{
CompileItem compiler (ctx, compile_fns, concrete, ref_locus);
item->accept_vis (compiler);
@@ -61,8 +60,8 @@ public:
&resolved_type);
rust_assert (ok);
- Btype *type = TyTyResolveCompile::compile (ctx, resolved_type);
- Bexpression *value = CompileExpr::Compile (var.get_expr (), ctx);
+ tree type = TyTyResolveCompile::compile (ctx, resolved_type);
+ tree value = CompileExpr::Compile (var.get_expr (), ctx);
const Resolver::CanonicalPath *canonical_path = nullptr;
ok = ctx->get_mappings ()->lookup_canonical_path (
@@ -97,8 +96,8 @@ public:
&resolved_type);
rust_assert (ok);
- ::Btype *type = TyTyResolveCompile::compile (ctx, resolved_type);
- Bexpression *value = CompileExpr::Compile (constant.get_expr (), ctx);
+ tree type = TyTyResolveCompile::compile (ctx, resolved_type);
+ tree value = CompileExpr::Compile (constant.get_expr (), ctx);
const Resolver::CanonicalPath *canonical_path = nullptr;
ok = ctx->get_mappings ()->lookup_canonical_path (
@@ -107,7 +106,7 @@ public:
rust_assert (ok);
std::string ident = canonical_path->get ();
- Bexpression *const_expr
+ tree const_expr
= ctx->get_backend ()->named_constant_expression (type, ident, value,
constant.get_locus ());
@@ -148,14 +147,14 @@ public:
// items can be forward compiled which means we may not need to invoke this
// code. We might also have already compiled this generic function as well.
- Bfunction *lookup = nullptr;
+ tree lookup = NULL_TREE;
if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
fntype->get_id (), fntype))
{
// has this been added to the list then it must be finished
if (ctx->function_completed (lookup))
{
- Bfunction *dummy = nullptr;
+ tree dummy = NULL_TREE;
if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
{
ctx->insert_function_decl (fntype, lookup);
@@ -174,7 +173,7 @@ public:
fntype->override_context ();
}
- ::Btype *compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
+ tree compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
unsigned int flags = 0;
bool is_main_fn = function.get_function_name ().compare ("main") == 0;
@@ -202,7 +201,7 @@ public:
asm_name = ctx->mangle_item (fntype, *canonical_path);
}
- Bfunction *fndecl
+ tree fndecl
= ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
asm_name, flags, function.get_locus ());
ctx->insert_function_decl (fntype, fndecl);
@@ -262,12 +261,12 @@ public:
ok = compile_locals_for_block (*rib, fndecl, locals);
rust_assert (ok);
- Bblock *enclosing_scope = NULL;
+ tree enclosing_scope = NULL_TREE;
HIR::BlockExpr *function_body = function.get_definition ().get ();
Location start_location = function_body->get_locus ();
Location end_location = function_body->get_closing_locus ();
- Bblock *code_block
+ tree code_block
= ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
start_location, end_location);
ctx->push_block (code_block);
@@ -275,10 +274,10 @@ public:
Bvariable *return_address = nullptr;
if (function.has_function_return_type ())
{
- Btype *return_type = TyTyResolveCompile::compile (ctx, tyret);
+ tree return_type = TyTyResolveCompile::compile (ctx, tyret);
bool address_is_taken = false;
- Bstatement *ret_var_stmt = nullptr;
+ tree ret_var_stmt = NULL_TREE;
return_address = ctx->get_backend ()->temporary_variable (
fndecl, code_block, return_type, NULL, address_is_taken,
@@ -347,7 +346,7 @@ protected:
bool compile_fns;
TyTy::BaseType *concrete;
- Bexpression *reference;
+ tree reference;
Location ref_locus;
};
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index d571d4a..cb3f0df 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -40,7 +40,7 @@ ResolvePathRef::visit (HIR::PathInExpression &expr)
expr.get_mappings (), expr.get_locus (), false);
}
-Bexpression *
+tree
ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
const Analysis::NodeMapping &mappings,
Location expr_locus, bool is_qualified_path)
@@ -76,7 +76,7 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
}
// might be a constant
- Bexpression *constant_expr;
+ tree constant_expr;
if (ctx->lookup_const_decl (ref, &constant_expr))
return constant_expr;
@@ -92,7 +92,7 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
if (lookup->get_kind () == TyTy::TypeKind::FNDEF)
{
TyTy::FnType *fntype = static_cast<TyTy::FnType *> (lookup);
- Bfunction *fn = nullptr;
+ tree fn = NULL_TREE;
if (ctx->lookup_function_decl (fntype->get_ty_ref (), &fn))
{
return ctx->get_backend ()->function_code_expression (fn, expr_locus);
@@ -104,7 +104,7 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
is_qualified_path);
}
-Bexpression *
+tree
ResolvePathRef::query_compile (HirId ref, TyTy::BaseType *lookup,
const HIR::PathIdentSegment &final_segment,
const Analysis::NodeMapping &mappings,
diff --git a/gcc/rust/backend/rust-compile-resolve-path.h b/gcc/rust/backend/rust-compile-resolve-path.h
index ecb89b3..56f82d1 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.h
+++ b/gcc/rust/backend/rust-compile-resolve-path.h
@@ -30,15 +30,14 @@ class ResolvePathRef : public HIRCompileBase
using Rust::Compile::HIRCompileBase::visit;
public:
- static Bexpression *Compile (HIR::QualifiedPathInExpression &expr,
- Context *ctx)
+ static tree Compile (HIR::QualifiedPathInExpression &expr, Context *ctx)
{
ResolvePathRef resolver (ctx);
expr.accept_vis (resolver);
return resolver.resolved;
}
- static Bexpression *Compile (HIR::PathInExpression &expr, Context *ctx)
+ static tree Compile (HIR::PathInExpression &expr, Context *ctx)
{
ResolvePathRef resolver (ctx);
expr.accept_vis (resolver);
@@ -54,16 +53,16 @@ private:
: HIRCompileBase (ctx), resolved (ctx->get_backend ()->error_expression ())
{}
- Bexpression *resolve (const HIR::PathIdentSegment &final_segment,
- const Analysis::NodeMapping &mappings, Location locus,
- bool is_qualified_path);
+ tree resolve (const HIR::PathIdentSegment &final_segment,
+ const Analysis::NodeMapping &mappings, Location locus,
+ bool is_qualified_path);
- Bexpression *query_compile (HirId ref, TyTy::BaseType *lookup,
- const HIR::PathIdentSegment &final_segment,
- const Analysis::NodeMapping &mappings,
- Location expr_locus, bool is_qualified_path);
+ tree query_compile (HirId ref, TyTy::BaseType *lookup,
+ const HIR::PathIdentSegment &final_segment,
+ const Analysis::NodeMapping &mappings,
+ Location expr_locus, bool is_qualified_path);
- Bexpression *resolved;
+ tree resolved;
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h
index 754c5d2..f3ee69d 100644
--- a/gcc/rust/backend/rust-compile-stmt.h
+++ b/gcc/rust/backend/rust-compile-stmt.h
@@ -31,7 +31,7 @@ class CompileStmt : public HIRCompileBase
using Rust::Compile::HIRCompileBase::visit;
public:
- static Bexpression *Compile (HIR::Stmt *stmt, Context *ctx)
+ static tree Compile (HIR::Stmt *stmt, Context *ctx)
{
CompileStmt compiler (ctx);
stmt->accept_vis (compiler);
@@ -56,8 +56,8 @@ public:
&resolved_type);
rust_assert (ok);
- ::Btype *type = TyTyResolveCompile::compile (ctx, resolved_type);
- Bexpression *value = CompileExpr::Compile (constant.get_expr (), ctx);
+ tree type = TyTyResolveCompile::compile (ctx, resolved_type);
+ tree value = CompileExpr::Compile (constant.get_expr (), ctx);
const Resolver::CanonicalPath *canonical_path = nullptr;
ok = ctx->get_mappings ()->lookup_canonical_path (
@@ -66,7 +66,7 @@ public:
rust_assert (ok);
std::string ident = canonical_path->get ();
- Bexpression *const_expr
+ tree const_expr
= ctx->get_backend ()->named_constant_expression (type, ident, value,
constant.get_locus ());
@@ -101,7 +101,7 @@ public:
return;
}
- Bexpression *init = CompileExpr::Compile (stmt.get_init_expr (), ctx);
+ tree init = CompileExpr::Compile (stmt.get_init_expr (), ctx);
// FIXME use error_mark_node, check that CompileExpr returns error_mark_node
// on failure and make this an assertion
if (init == nullptr)
@@ -118,7 +118,7 @@ public:
auto fnctx = ctx->peek_fn ();
if (ty->is_unit ())
{
- Bstatement *expr_stmt
+ tree expr_stmt
= ctx->get_backend ()->expression_statement (fnctx.fndecl, init);
ctx->add_statement (expr_stmt);
}
@@ -132,7 +132,7 @@ public:
private:
CompileStmt (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {}
- Bexpression *translated;
+ tree translated;
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-struct-field-expr.h b/gcc/rust/backend/rust-compile-struct-field-expr.h
index 553e870..6754e8c 100644
--- a/gcc/rust/backend/rust-compile-struct-field-expr.h
+++ b/gcc/rust/backend/rust-compile-struct-field-expr.h
@@ -30,7 +30,7 @@ class CompileStructExprField : public HIRCompileBase
using Rust::Compile::HIRCompileBase::visit;
public:
- static Bexpression *Compile (HIR::StructExprField *field, Context *ctx)
+ static tree Compile (HIR::StructExprField *field, Context *ctx)
{
CompileStructExprField compiler (ctx);
field->accept_vis (compiler);
@@ -49,7 +49,7 @@ private:
: HIRCompileBase (ctx), translated (nullptr)
{}
- Bexpression *translated;
+ tree translated;
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h
index 180b971..04a3ecd 100644
--- a/gcc/rust/backend/rust-compile-tyty.h
+++ b/gcc/rust/backend/rust-compile-tyty.h
@@ -34,7 +34,7 @@ namespace Compile {
class TyTyCompile : public TyTy::TyVisitor
{
public:
- static ::Btype *compile (::Backend *backend, TyTy::BaseType *ty)
+ static tree compile (::Backend *backend, TyTy::BaseType *ty)
{
TyTyCompile compiler (backend);
ty->accept_vis (compiler);
@@ -72,15 +72,15 @@ public:
void visit (TyTy::FnType &type) override
{
- Backend::Btyped_identifier receiver;
- std::vector<Backend::Btyped_identifier> parameters;
- std::vector<Backend::Btyped_identifier> results;
+ Backend::typed_identifier receiver;
+ std::vector<Backend::typed_identifier> parameters;
+ std::vector<Backend::typed_identifier> results;
if (!type.get_return_type ()->is_unit ())
{
auto hir_type = type.get_return_type ();
auto ret = TyTyCompile::compile (backend, hir_type);
- results.push_back (Backend::Btyped_identifier (
+ results.push_back (Backend::typed_identifier (
"_", ret, mappings->lookup_location (hir_type->get_ref ())));
}
@@ -90,7 +90,7 @@ public:
auto param_tyty = params.second;
auto compiled_param_type = TyTyCompile::compile (backend, param_tyty);
- auto compiled_param = Backend::Btyped_identifier (
+ auto compiled_param = Backend::typed_identifier (
param_pattern->as_string (), compiled_param_type,
mappings->lookup_location (param_tyty->get_ref ()));
@@ -227,7 +227,7 @@ public:
void visit (TyTy::StrType &) override
{
- Btype *raw_str = backend->raw_str_type ();
+ tree raw_str = backend->raw_str_type ();
translated
= backend->named_type ("str", raw_str, Linemap::predeclared_location ());
}
@@ -248,7 +248,7 @@ private:
{}
::Backend *backend;
- ::Btype *translated;
+ tree translated;
Analysis::Mappings *mappings;
};
diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h
index 7a86e15..a964fa2 100644
--- a/gcc/rust/backend/rust-compile-var-decl.h
+++ b/gcc/rust/backend/rust-compile-var-decl.h
@@ -29,8 +29,7 @@ class CompileVarDecl : public HIRCompileBase
using Rust::Compile::HIRCompileBase::visit;
public:
- static ::Bvariable *compile (::Bfunction *fndecl, HIR::Stmt *stmt,
- Context *ctx)
+ static ::Bvariable *compile (tree fndecl, HIR::Stmt *stmt, Context *ctx)
{
CompileVarDecl compiler (ctx, fndecl);
stmt->accept_vis (compiler);
@@ -64,13 +63,13 @@ public:
}
private:
- CompileVarDecl (Context *ctx, ::Bfunction *fndecl)
+ CompileVarDecl (Context *ctx, tree fndecl)
: HIRCompileBase (ctx), fndecl (fndecl), translated_type (nullptr),
translated (nullptr)
{}
- ::Bfunction *fndecl;
- ::Btype *translated_type;
+ tree fndecl;
+ tree translated_type;
Location locus;
::Bvariable *translated;
};
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index e9aca2c..579b323 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -72,7 +72,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
{
rust_assert (tyty->get_kind () == TyTy::TypeKind::ADT);
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (tyty);
- Btype *compiled_adt_type = TyTyResolveCompile::compile (ctx, tyty);
+ tree compiled_adt_type = TyTyResolveCompile::compile (ctx, tyty);
rust_assert (!adt->is_enum ());
rust_assert (adt->number_of_variants () == 1);
@@ -80,7 +80,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
// this assumes all fields are in order from type resolution and if a
// base struct was specified those fields are filed via accesors
- std::vector<Bexpression *> vals;
+ std::vector<tree> vals;
for (size_t i = 0; i < expr.get_arguments ().size (); i++)
{
auto &argument = expr.get_arguments ().at (i);
@@ -150,7 +150,7 @@ CompileExpr::visit (HIR::CallExpr &expr)
required_num_args = fn->num_params ();
}
- std::vector<Bexpression *> args;
+ std::vector<tree> args;
for (size_t i = 0; i < expr.get_arguments ().size (); i++)
{
auto &argument = expr.get_arguments ().at (i);
@@ -195,7 +195,7 @@ void
CompileExpr::visit (HIR::MethodCallExpr &expr)
{
// method receiver
- Bexpression *self = CompileExpr::Compile (expr.get_receiver ().get (), ctx);
+ tree self = CompileExpr::Compile (expr.get_receiver ().get (), ctx);
// lookup the resolved name
NodeId resolved_node_id = UNKNOWN_NODEID;
@@ -242,220 +242,21 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
const TyTy::DynamicObjectType *dyn
= static_cast<const TyTy::DynamicObjectType *> (receiver->get_root ());
- size_t offs = 0;
- const Resolver::TraitItemReference *ref = nullptr;
- for (auto &bound : dyn->get_object_items ())
- {
- const Resolver::TraitItemReference *item = bound.first;
- auto t = item->get_tyty ();
- rust_assert (t->get_kind () == TyTy::TypeKind::FNDEF);
- auto ft = static_cast<TyTy::FnType *> (t);
-
- if (ft->get_id () == fntype->get_id ())
- {
- ref = item;
- break;
- }
- offs++;
- }
-
- if (ref == nullptr)
- {
- translated = ctx->get_backend ()->error_expression ();
- return;
- }
-
- // get any indirection sorted out
- auto receiver_ref = self;
- if (receiver->get_kind () == TyTy::TypeKind::REF)
- {
- TyTy::ReferenceType *r
- = static_cast<TyTy::ReferenceType *> (receiver);
- auto indirect_ty = r->get_base ();
- Btype *indrect_compiled_tyty
- = TyTyResolveCompile::compile (ctx, indirect_ty);
-
- Bexpression *indirect
- = ctx->get_backend ()->indirect_expression (indrect_compiled_tyty,
- receiver_ref, true,
- expr.get_locus ());
- receiver_ref = indirect;
- }
-
- // access the offs + 1 for the fnptr and offs=0 for the reciever obj
- Bexpression *self_argument
- = ctx->get_backend ()->struct_field_expression (receiver_ref, 0,
- expr.get_locus ());
-
- // access the vtable for the fn
- Bexpression *fn_vtable_access
- = ctx->get_backend ()->struct_field_expression (receiver_ref, offs + 1,
- expr.get_locus ());
-
- // cast it to the correct fntype
- Btype *expected_fntype = TyTyResolveCompile::compile (ctx, fntype, true);
- Bexpression *fn_convert_expr
- = ctx->get_backend ()->convert_expression (expected_fntype,
- fn_vtable_access,
- expr.get_locus ());
-
- fncontext fnctx = ctx->peek_fn ();
- Bblock *enclosing_scope = ctx->peek_enclosing_scope ();
- bool is_address_taken = false;
- Bstatement *ret_var_stmt = nullptr;
-
- Bvariable *fn_convert_expr_tmp = ctx->get_backend ()->temporary_variable (
- fnctx.fndecl, enclosing_scope, expected_fntype, fn_convert_expr,
- is_address_taken, expr.get_locus (), &ret_var_stmt);
- ctx->add_statement (ret_var_stmt);
-
- std::vector<Bexpression *> args;
- args.push_back (self_argument);
- for (auto &argument : expr.get_arguments ())
- {
- Bexpression *compiled_expr
- = CompileExpr::Compile (argument.get (), ctx);
- args.push_back (compiled_expr);
- }
-
- Bexpression *fn_expr
- = ctx->get_backend ()->var_expression (fn_convert_expr_tmp,
- expr.get_locus ());
+ std::vector<HIR::Expr *> arguments;
+ for (auto &arg : expr.get_arguments ())
+ arguments.push_back (arg.get ());
- translated
- = ctx->get_backend ()->call_expression (fnctx.fndecl, fn_expr, args,
- nullptr, expr.get_locus ());
+ translated = compile_dyn_dispatch_call (dyn, receiver, fntype, self,
+ arguments, expr.get_locus ());
return;
}
- // address of compiled function
- Bexpression *fn_expr = ctx->get_backend ()->error_expression ();
-
// lookup compiled functions since it may have already been compiled
- Bfunction *fn = nullptr;
- if (ctx->lookup_function_decl (fntype->get_ty_ref (), &fn))
- {
- fn_expr
- = ctx->get_backend ()->function_code_expression (fn, expr.get_locus ());
- }
- else
- {
- // Now we can try and resolve the address since this might be a forward
- // declared function, generic function which has not be compiled yet or
- // its an not yet trait bound function
- HIR::ImplItem *resolved_item = ctx->get_mappings ()->lookup_hir_implitem (
- expr.get_mappings ().get_crate_num (), ref, nullptr);
- if (resolved_item == nullptr)
- {
- // it might be resolved to a trait item
- HIR::TraitItem *trait_item
- = ctx->get_mappings ()->lookup_hir_trait_item (
- expr.get_mappings ().get_crate_num (), ref);
- HIR::Trait *trait = ctx->get_mappings ()->lookup_trait_item_mapping (
- trait_item->get_mappings ().get_hirid ());
-
- Resolver::TraitReference *trait_ref
- = &Resolver::TraitReference::error_node ();
- bool ok = ctx->get_tyctx ()->lookup_trait_reference (
- trait->get_mappings ().get_defid (), &trait_ref);
- rust_assert (ok);
-
- // the type resolver can only resolve type bounds to their trait
- // item so its up to us to figure out if this path should resolve
- // to an trait-impl-block-item or if it can be defaulted to the
- // trait-impl-item's definition
-
- auto root = receiver->get_root ();
- std::vector<Resolver::PathProbeCandidate> candidates
- = Resolver::PathProbeType::Probe (
- root, expr.get_method_name ().get_segment (), true, false, true);
-
- if (candidates.size () == 0)
- {
- // this means we are defaulting back to the trait_item if
- // possible
- Resolver::TraitItemReference *trait_item_ref = nullptr;
- bool ok = trait_ref->lookup_hir_trait_item (*trait_item,
- &trait_item_ref);
- rust_assert (ok); // found
- rust_assert (trait_item_ref->is_optional ()); // has definition
-
- // FIXME Optional means it has a definition and an associated
- // block which can be a default implementation, if it does not
- // contain an implementation we should actually return
- // error_mark_node
-
- TyTy::BaseType *self_type = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (
- expr.get_receiver ()->get_mappings ().get_hirid (),
- &self_type))
- {
- rust_error_at (expr.get_locus (),
- "failed to resolve type for self param");
- return;
- }
-
- fn_expr = CompileTraitItem::Compile (
- self_type, trait_item_ref->get_hir_trait_item (), ctx, fntype,
- true, expr.get_locus ());
- }
- else
- {
- std::vector<Resolver::Adjustment> adjustments;
- Resolver::PathProbeCandidate *candidate
- = Resolver::MethodResolution::Select (candidates, root,
- adjustments);
-
- // FIXME this will be a case to return error_mark_node, there is
- // an error scenario where a Trait Foo has a method Bar, but this
- // receiver does not implement this trait or has an incompatible
- // implementation and we should just return error_mark_node
- rust_assert (candidate != nullptr);
- rust_assert (candidate->is_impl_candidate ());
-
- HIR::ImplItem *impl_item = candidate->item.impl.impl_item;
-
- TyTy::BaseType *self_type = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (
- expr.get_receiver ()->get_mappings ().get_hirid (),
- &self_type))
- {
- rust_error_at (expr.get_locus (),
- "failed to resolve type for self param");
- return;
- }
-
- if (!fntype->has_subsititions_defined ())
- fn_expr
- = CompileInherentImplItem::Compile (self_type, impl_item, ctx,
- true);
- else
- fn_expr
- = CompileInherentImplItem::Compile (self_type, impl_item, ctx,
- true, fntype);
- }
- }
- else
- {
- TyTy::BaseType *self_type = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (
- expr.get_receiver ()->get_mappings ().get_hirid (), &self_type))
- {
- rust_error_at (expr.get_locus (),
- "failed to resolve type for self param");
- return;
- }
-
- if (!fntype->has_subsititions_defined ())
- fn_expr
- = CompileInherentImplItem::Compile (self_type, resolved_item, ctx,
- true);
- else
- fn_expr
- = CompileInherentImplItem::Compile (self_type, resolved_item, ctx,
- true, fntype);
- }
- }
+ HIR::PathExprSegment method_name = expr.get_method_name ();
+ HIR::PathIdentSegment segment_name = method_name.get_segment ();
+ tree fn_expr
+ = resolve_method_address (fntype, ref, receiver, segment_name,
+ expr.get_mappings (), expr.get_locus ());
// lookup the autoderef mappings
std::vector<Resolver::Adjustment> *adjustments = nullptr;
@@ -474,7 +275,7 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
break;
case Resolver::Adjustment::AdjustmentType::DEREF_REF:
- Btype *expected_type
+ tree expected_type
= TyTyResolveCompile::compile (ctx, adjustment.get_expected ());
self = ctx->get_backend ()->indirect_expression (
expected_type, self, true, /* known_valid*/
@@ -483,7 +284,7 @@ CompileExpr::visit (HIR::MethodCallExpr &expr)
}
}
- std::vector<Bexpression *> args;
+ std::vector<tree> args;
args.push_back (self); // adjusted self
// normal args
@@ -521,7 +322,7 @@ void
CompileBlock::visit (HIR::BlockExpr &expr)
{
fncontext fnctx = ctx->peek_fn ();
- Bfunction *fndecl = fnctx.fndecl;
+ tree fndecl = fnctx.fndecl;
Location start_location = expr.get_locus ();
Location end_location = expr.get_closing_locus ();
auto body_mappings = expr.get_mappings ();
@@ -537,10 +338,9 @@ CompileBlock::visit (HIR::BlockExpr &expr)
bool ok = compile_locals_for_block (*rib, fndecl, locals);
rust_assert (ok);
- Bblock *enclosing_scope = ctx->peek_enclosing_scope ();
- Bblock *new_block
- = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
- start_location, end_location);
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree new_block = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
+ start_location, end_location);
ctx->push_block (new_block);
for (auto &s : expr.get_statements ())
@@ -548,7 +348,7 @@ CompileBlock::visit (HIR::BlockExpr &expr)
auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
if (compiled_expr != nullptr)
{
- Bstatement *compiled_stmt
+ tree compiled_stmt
= ctx->get_backend ()->expression_statement (fnctx.fndecl,
compiled_expr);
ctx->add_statement (compiled_stmt);
@@ -559,23 +359,22 @@ CompileBlock::visit (HIR::BlockExpr &expr)
{
// the previous passes will ensure this is a valid return or
// a valid trailing expression
- Bexpression *compiled_expr = CompileExpr::Compile (expr.expr.get (), ctx);
+ tree compiled_expr = CompileExpr::Compile (expr.expr.get (), ctx);
if (compiled_expr != nullptr)
{
if (result == nullptr)
{
- Bstatement *final_stmt
+ tree final_stmt
= ctx->get_backend ()->expression_statement (fnctx.fndecl,
compiled_expr);
ctx->add_statement (final_stmt);
}
else
{
- Bexpression *result_reference
- = ctx->get_backend ()->var_expression (
- result, expr.get_final_expr ()->get_locus ());
+ tree result_reference = ctx->get_backend ()->var_expression (
+ result, expr.get_final_expr ()->get_locus ());
- Bstatement *assignment
+ tree assignment
= ctx->get_backend ()->assignment_statement (fnctx.fndecl,
result_reference,
compiled_expr,
@@ -593,11 +392,9 @@ void
CompileConditionalBlocks::visit (HIR::IfExpr &expr)
{
fncontext fnctx = ctx->peek_fn ();
- Bfunction *fndecl = fnctx.fndecl;
- Bexpression *condition_expr
- = CompileExpr::Compile (expr.get_if_condition (), ctx);
- Bblock *then_block
- = CompileBlock::compile (expr.get_if_block (), ctx, result);
+ tree fndecl = fnctx.fndecl;
+ tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
+ tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
translated
= ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block,
@@ -608,13 +405,10 @@ void
CompileConditionalBlocks::visit (HIR::IfExprConseqElse &expr)
{
fncontext fnctx = ctx->peek_fn ();
- Bfunction *fndecl = fnctx.fndecl;
- Bexpression *condition_expr
- = CompileExpr::Compile (expr.get_if_condition (), ctx);
- Bblock *then_block
- = CompileBlock::compile (expr.get_if_block (), ctx, result);
- Bblock *else_block
- = CompileBlock::compile (expr.get_else_block (), ctx, result);
+ tree fndecl = fnctx.fndecl;
+ tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
+ tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
+ tree else_block = CompileBlock::compile (expr.get_else_block (), ctx, result);
translated
= ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block,
@@ -625,23 +419,20 @@ void
CompileConditionalBlocks::visit (HIR::IfExprConseqIf &expr)
{
fncontext fnctx = ctx->peek_fn ();
- Bfunction *fndecl = fnctx.fndecl;
- Bexpression *condition_expr
- = CompileExpr::Compile (expr.get_if_condition (), ctx);
- Bblock *then_block
- = CompileBlock::compile (expr.get_if_block (), ctx, result);
+ tree fndecl = fnctx.fndecl;
+ tree condition_expr = CompileExpr::Compile (expr.get_if_condition (), ctx);
+ tree then_block = CompileBlock::compile (expr.get_if_block (), ctx, result);
// else block
std::vector<Bvariable *> locals;
Location start_location = expr.get_conseq_if_expr ()->get_locus ();
Location end_location = expr.get_conseq_if_expr ()->get_locus (); // FIXME
- Bblock *enclosing_scope = ctx->peek_enclosing_scope ();
- Bblock *else_block
- = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
- start_location, end_location);
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
+ tree else_block = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
+ start_location, end_location);
ctx->push_block (else_block);
- Bstatement *else_stmt_decl
+ tree else_stmt_decl
= CompileConditionalBlocks::compile (expr.get_conseq_if_expr (), ctx,
result);
ctx->add_statement (else_stmt_decl);
@@ -681,7 +472,7 @@ CompileStructExprField::visit (HIR::StructExprFieldIdentifier &field)
void
HIRCompileBase::compile_function_body (
- Bfunction *fndecl, std::unique_ptr<HIR::BlockExpr> &function_body,
+ tree fndecl, std::unique_ptr<HIR::BlockExpr> &function_body,
bool has_return_type)
{
for (auto &s : function_body->get_statements ())
@@ -689,7 +480,7 @@ HIRCompileBase::compile_function_body (
auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
if (compiled_expr != nullptr)
{
- Bstatement *compiled_stmt
+ tree compiled_stmt
= ctx->get_backend ()->expression_statement (fndecl, compiled_expr);
ctx->add_statement (compiled_stmt);
}
@@ -699,14 +490,14 @@ HIRCompileBase::compile_function_body (
{
// the previous passes will ensure this is a valid return
// or a valid trailing expression
- Bexpression *compiled_expr
+ tree compiled_expr
= CompileExpr::Compile (function_body->expr.get (), ctx);
if (compiled_expr != nullptr)
{
if (has_return_type)
{
- std::vector<Bexpression *> retstmts;
+ std::vector<tree> retstmts;
retstmts.push_back (compiled_expr);
auto ret = ctx->get_backend ()->return_statement (
@@ -716,7 +507,7 @@ HIRCompileBase::compile_function_body (
}
else
{
- Bstatement *final_stmt
+ tree final_stmt
= ctx->get_backend ()->expression_statement (fndecl,
compiled_expr);
ctx->add_statement (final_stmt);
@@ -726,7 +517,7 @@ HIRCompileBase::compile_function_body (
}
bool
-HIRCompileBase::compile_locals_for_block (Resolver::Rib &rib, Bfunction *fndecl,
+HIRCompileBase::compile_locals_for_block (Resolver::Rib &rib, tree fndecl,
std::vector<Bvariable *> &locals)
{
rib.iterate_decls ([&] (NodeId n, Location) mutable -> bool {
@@ -760,10 +551,9 @@ HIRCompileBase::compile_locals_for_block (Resolver::Rib &rib, Bfunction *fndecl,
return true;
}
-Bexpression *
-HIRCompileBase::coercion_site (Bexpression *compiled_ref,
- TyTy::BaseType *actual, TyTy::BaseType *expected,
- Location locus)
+tree
+HIRCompileBase::coercion_site (tree compiled_ref, TyTy::BaseType *actual,
+ TyTy::BaseType *expected, Location locus)
{
auto root_actual_kind = actual->get_root ()->get_kind ();
auto root_expected_kind = expected->get_root ()->get_kind ();
@@ -779,14 +569,14 @@ HIRCompileBase::coercion_site (Bexpression *compiled_ref,
return compiled_ref;
}
-Bexpression *
-HIRCompileBase::coerce_to_dyn_object (Bexpression *compiled_ref,
+tree
+HIRCompileBase::coerce_to_dyn_object (tree compiled_ref,
const TyTy::BaseType *actual,
const TyTy::BaseType *expected,
const TyTy::DynamicObjectType *ty,
Location locus)
{
- Btype *dynamic_object = TyTyResolveCompile::compile (ctx, ty);
+ tree dynamic_object = TyTyResolveCompile::compile (ctx, ty);
//' this assumes ordering and current the structure is
// __trait_object_ptr
@@ -796,7 +586,7 @@ HIRCompileBase::coerce_to_dyn_object (Bexpression *compiled_ref,
std::vector<std::pair<Resolver::TraitReference *, HIR::ImplBlock *>>
probed_bounds_for_receiver = Resolver::TypeBoundsProbe::Probe (root);
- std::vector<Bexpression *> vals;
+ std::vector<tree> vals;
vals.push_back (compiled_ref);
for (auto &bound : ty->get_object_items ())
{
@@ -809,14 +599,14 @@ HIRCompileBase::coerce_to_dyn_object (Bexpression *compiled_ref,
vals.push_back (address);
}
- Bexpression *constructed_trait_object
+ tree constructed_trait_object
= ctx->get_backend ()->constructor_expression (dynamic_object, vals, -1,
locus);
fncontext fnctx = ctx->peek_fn ();
- Bblock *enclosing_scope = ctx->peek_enclosing_scope ();
+ tree enclosing_scope = ctx->peek_enclosing_scope ();
bool is_address_taken = false;
- Bstatement *ret_var_stmt = nullptr;
+ tree ret_var_stmt = NULL_TREE;
Bvariable *dyn_tmp = ctx->get_backend ()->temporary_variable (
fnctx.fndecl, enclosing_scope, dynamic_object, constructed_trait_object,
@@ -858,7 +648,7 @@ HIRCompileBase::coerce_to_dyn_object (Bexpression *compiled_ref,
return resulting_dyn_object_ref;
}
-Bexpression *
+tree
HIRCompileBase::compute_address_for_trait_item (
const Resolver::TraitItemReference *ref,
const TyTy::TypeBoundPredicate *predicate,
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index 54cb6113..f36096b 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -452,11 +452,8 @@ public:
expr.get_locus ());
}
- /* Compound assignment expression is compiled away. */
void visit (AST::CompoundAssignmentExpr &expr) override
{
- /* First we need to find the corresponding arithmetic or logical operator.
- */
ArithmeticOrLogicalOperator op;
switch (expr.get_expr_type ())
{
@@ -503,15 +500,10 @@ public:
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
mappings->get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- HIR::Expr *operator_expr
- = new HIR::ArithmeticOrLogicalExpr (mapping, asignee_expr->clone_expr (),
- std::unique_ptr<HIR::Expr> (value),
- op, expr.get_locus ());
- translated
- = new HIR::AssignmentExpr (mapping,
- std::unique_ptr<HIR::Expr> (asignee_expr),
- std::unique_ptr<HIR::Expr> (operator_expr),
- expr.get_locus ());
+
+ translated = new HIR::CompoundAssignmentExpr (
+ mapping, std::unique_ptr<HIR::Expr> (asignee_expr),
+ std::unique_ptr<HIR::Expr> (value), op, expr.get_locus ());
}
void visit (AST::StructExprStruct &struct_expr) override
diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h
index db0425f..65a4921 100644
--- a/gcc/rust/hir/rust-ast-lower-item.h
+++ b/gcc/rust/hir/rust-ast-lower-item.h
@@ -613,29 +613,6 @@ public:
if (trait.has_generics ())
{
generic_params = lower_generic_params (trait.get_generic_params ());
-
- for (auto &generic_param : generic_params)
- {
- switch (generic_param->get_kind ())
- {
- case HIR::GenericParam::GenericKind::TYPE: {
- const HIR::TypeParam &t
- = static_cast<const HIR::TypeParam &> (*generic_param);
-
- if (t.has_type ())
- {
- // see https://github.com/rust-lang/rust/issues/36887
- rust_error_at (
- t.get_locus (),
- "defaults for type parameters are not allowed here");
- }
- }
- break;
-
- default:
- break;
- }
- }
}
std::vector<std::unique_ptr<HIR::TypeParamBound>> type_param_bounds;
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 575d1f6..901feda 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -666,6 +666,80 @@ protected:
}
};
+class CompoundAssignmentExpr : public OperatorExpr
+{
+public:
+ using ExprType = ArithmeticOrLogicalOperator;
+
+private:
+ // Note: overloading trait specified in comments
+ ExprType expr_type;
+ std::unique_ptr<Expr> right_expr;
+
+public:
+ std::string as_string () const override;
+
+ ExprType get_expr_type () const { return expr_type; }
+
+ // Use pointers in constructor to enable polymorphism
+ CompoundAssignmentExpr (Analysis::NodeMapping mappings,
+ std::unique_ptr<Expr> value_to_assign_to,
+ std::unique_ptr<Expr> value_to_assign,
+ ExprType expr_kind, Location locus)
+ : OperatorExpr (std::move (mappings), std::move (value_to_assign_to),
+ AST::AttrVec (), locus),
+ expr_type (expr_kind), right_expr (std::move (value_to_assign))
+ {}
+ // outer attributes not allowed
+
+ // Have clone in copy constructor
+ CompoundAssignmentExpr (CompoundAssignmentExpr const &other)
+ : OperatorExpr (other), expr_type (other.expr_type),
+ right_expr (other.right_expr->clone_expr ())
+ {}
+
+ // Overload assignment operator to clone
+ CompoundAssignmentExpr &operator= (CompoundAssignmentExpr const &other)
+ {
+ OperatorExpr::operator= (other);
+ // main_or_left_expr = other.main_or_left_expr->clone_expr();
+ right_expr = other.right_expr->clone_expr ();
+ expr_type = other.expr_type;
+ // outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ CompoundAssignmentExpr (CompoundAssignmentExpr &&other) = default;
+ CompoundAssignmentExpr &operator= (CompoundAssignmentExpr &&other) = default;
+
+ void accept_vis (HIRVisitor &vis) override;
+
+ std::unique_ptr<Expr> &get_left_expr ()
+ {
+ rust_assert (main_or_left_expr != nullptr);
+ return main_or_left_expr;
+ }
+
+ std::unique_ptr<Expr> &get_right_expr ()
+ {
+ rust_assert (right_expr != nullptr);
+ return right_expr;
+ }
+
+ void visit_lhs (HIRVisitor &vis) { main_or_left_expr->accept_vis (vis); }
+ void visit_rhs (HIRVisitor &vis) { right_expr->accept_vis (vis); }
+
+protected:
+ /* Use covariance to implement clone function as returning this object rather
+ * than base */
+ CompoundAssignmentExpr *clone_expr_without_block_impl () const override
+ {
+ return new CompoundAssignmentExpr (*this);
+ }
+};
+
// Expression in parentheses (i.e. like literally just any 3 + (2 * 6))
class GroupedExpr : public ExprWithoutBlock
{
@@ -1635,7 +1709,6 @@ class MethodCallExpr : public ExprWithoutBlock
{
std::unique_ptr<Expr> receiver;
PathExprSegment method_name;
- // inlined form of CallParams
std::vector<std::unique_ptr<Expr> > params;
Location locus;
@@ -1643,10 +1716,6 @@ class MethodCallExpr : public ExprWithoutBlock
public:
std::string as_string () const override;
- /*inline std::vector<std::unique_ptr<Expr>> get_params() const {
- return params;
- }*/
-
MethodCallExpr (Analysis::NodeMapping mappings,
std::unique_ptr<Expr> call_receiver,
PathExprSegment method_path,
diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc
index bacef82..843e32c 100644
--- a/gcc/rust/hir/tree/rust-hir-full-test.cc
+++ b/gcc/rust/hir/tree/rust-hir-full-test.cc
@@ -1316,6 +1316,67 @@ AssignmentExpr::as_string () const
}
std::string
+CompoundAssignmentExpr::as_string () const
+{
+ std::string operator_str;
+ operator_str.reserve (1);
+
+ // get operator string
+ switch (expr_type)
+ {
+ case ArithmeticOrLogicalOperator::ADD:
+ operator_str = "+";
+ break;
+ case ArithmeticOrLogicalOperator::SUBTRACT:
+ operator_str = "-";
+ break;
+ case ArithmeticOrLogicalOperator::MULTIPLY:
+ operator_str = "*";
+ break;
+ case ArithmeticOrLogicalOperator::DIVIDE:
+ operator_str = "/";
+ break;
+ case ArithmeticOrLogicalOperator::MODULUS:
+ operator_str = "%";
+ break;
+ case ArithmeticOrLogicalOperator::BITWISE_AND:
+ operator_str = "&";
+ break;
+ case ArithmeticOrLogicalOperator::BITWISE_OR:
+ operator_str = "|";
+ break;
+ case ArithmeticOrLogicalOperator::BITWISE_XOR:
+ operator_str = "^";
+ break;
+ case ArithmeticOrLogicalOperator::LEFT_SHIFT:
+ operator_str = "<<";
+ break;
+ case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
+ operator_str = ">>";
+ break;
+ default:
+ gcc_unreachable ();
+ break;
+ }
+
+ operator_str += "=";
+
+ std::string str ("CompoundAssignmentExpr: ");
+ if (main_or_left_expr == nullptr || right_expr == nullptr)
+ {
+ str += "error. this is probably a parsing failure.";
+ }
+ else
+ {
+ str += "\n left: " + main_or_left_expr->as_string ();
+ str += "\n right: " + right_expr->as_string ();
+ str += "\n operator: " + operator_str;
+ }
+
+ return str;
+}
+
+std::string
AsyncBlockExpr::as_string () const
{
std::string str = "AsyncBlockExpr: ";
@@ -3819,6 +3880,12 @@ AssignmentExpr::accept_vis (HIRVisitor &vis)
}
void
+CompoundAssignmentExpr::accept_vis (HIRVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
GroupedExpr::accept_vis (HIRVisitor &vis)
{
vis.visit (*this);
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h
index 0487446..ea125d9 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.h
+++ b/gcc/rust/hir/tree/rust-hir-visitor.h
@@ -47,6 +47,7 @@ public:
virtual void visit (LazyBooleanExpr &expr) = 0;
virtual void visit (TypeCastExpr &expr) = 0;
virtual void visit (AssignmentExpr &expr) = 0;
+ virtual void visit (CompoundAssignmentExpr &expr) = 0;
virtual void visit (GroupedExpr &expr) = 0;
virtual void visit (ArrayElemsValues &elems) = 0;
virtual void visit (ArrayElemsCopied &elems) = 0;
diff --git a/gcc/rust/lint/rust-lint-marklive-base.h b/gcc/rust/lint/rust-lint-marklive-base.h
index b67705b..e0494d7 100644
--- a/gcc/rust/lint/rust-lint-marklive-base.h
+++ b/gcc/rust/lint/rust-lint-marklive-base.h
@@ -53,7 +53,7 @@ public:
virtual void visit (HIR::LazyBooleanExpr &) override {}
virtual void visit (HIR::TypeCastExpr &) override {}
virtual void visit (HIR::AssignmentExpr &) override {}
-
+ virtual void visit (HIR::CompoundAssignmentExpr &) override {}
virtual void visit (HIR::GroupedExpr &) override {}
virtual void visit (HIR::ArrayElemsValues &) override {}
diff --git a/gcc/rust/lint/rust-lint-marklive.h b/gcc/rust/lint/rust-lint-marklive.h
index ca5d894..bcf792b 100644
--- a/gcc/rust/lint/rust-lint-marklive.h
+++ b/gcc/rust/lint/rust-lint-marklive.h
@@ -186,6 +186,12 @@ public:
expr.visit_rhs (*this);
}
+ void visit (HIR::CompoundAssignmentExpr &expr) override
+ {
+ expr.visit_lhs (*this);
+ expr.visit_rhs (*this);
+ }
+
void visit (HIR::IfExpr &expr) override
{
expr.get_if_condition ()->accept_vis (*this);
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index 86c9934..f60732c 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -35,29 +35,14 @@ class ResolveTraitItems : public ResolverBase
using Rust::Resolver::ResolverBase::visit;
public:
- static void go (AST::TraitItem *item, const CanonicalPath &self)
+ static void go (AST::TraitItem *item)
{
- ResolveTraitItems resolver (self);
+ ResolveTraitItems resolver;
item->accept_vis (resolver);
};
void visit (AST::TraitItemType &type) override
{
- // insert Self::type_alias for TypePath lookup
- auto path
- = self.append (ResolveTraitItemTypeToCanonicalPath::resolve (type));
- resolver->get_type_scope ().insert (
- path, type.get_node_id (), type.get_locus (), false,
- [&] (const CanonicalPath &, NodeId, Location locus) -> void {
- RichLocation r (type.get_locus ());
- r.add_range (locus);
- rust_error_at (r, "redefined multiple times");
- });
-
- // FIXME this stops the erronious unused decls which will be fixed later on
- resolver->get_type_scope ().append_reference_for_def (type.get_node_id (),
- type.get_node_id ());
-
for (auto &bound : type.get_type_param_bounds ())
ResolveTypeBound::go (bound.get (), type.get_node_id ());
}
@@ -189,11 +174,7 @@ public:
}
private:
- ResolveTraitItems (const CanonicalPath &self)
- : ResolverBase (UNKNOWN_NODEID), self (self)
- {}
-
- const CanonicalPath &self;
+ ResolveTraitItems () : ResolverBase (UNKNOWN_NODEID) {}
};
class ResolveItem : public ResolverBase
@@ -649,7 +630,7 @@ public:
for (auto &item : trait.get_trait_items ())
{
- ResolveTraitItems::go (item.get (), Self);
+ ResolveTraitItems::go (item.get ());
}
resolver->get_type_scope ().pop ();
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index 838d173..2bcf79d 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -101,6 +101,7 @@ protected:
using Rust::Resolver::ResolverBase::visit;
public:
+ // FIXME this should really only take AST::TypeNoBounds&
static CanonicalPath resolve (AST::Type &type,
bool include_generic_args = true,
bool type_resolve_generic_args = true)
@@ -121,6 +122,8 @@ public:
}
}
+ void visit (AST::ReferenceType &ref) override;
+
void visit (AST::TypePathSegmentGeneric &seg) override;
void visit (AST::TypePathSegment &seg) override;
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index 921b77c..9a0d349 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -439,8 +439,10 @@ ResolveTypeToCanonicalPath::visit (AST::TypePathSegmentGeneric &seg)
if (!seg.has_generic_args ())
{
- result = CanonicalPath::new_seg (seg.get_node_id (),
- seg.get_ident_segment ().as_string ());
+ auto ident_segment
+ = CanonicalPath::new_seg (seg.get_node_id (),
+ seg.get_ident_segment ().as_string ());
+ result = result.append (ident_segment);
return;
}
@@ -454,14 +456,18 @@ ResolveTypeToCanonicalPath::visit (AST::TypePathSegmentGeneric &seg)
{
std::string generics
= canonicalize_generic_args (seg.get_generic_args ());
- result = CanonicalPath::new_seg (seg.get_node_id (),
- seg.get_ident_segment ().as_string ()
- + "::" + generics);
+ auto generic_segment
+ = CanonicalPath::new_seg (seg.get_node_id (),
+ seg.get_ident_segment ().as_string ()
+ + "::" + generics);
+ result = result.append (generic_segment);
return;
}
- result = CanonicalPath::new_seg (seg.get_node_id (),
- seg.get_ident_segment ().as_string ());
+ auto ident_segment
+ = CanonicalPath::new_seg (seg.get_node_id (),
+ seg.get_ident_segment ().as_string ());
+ result = result.append (ident_segment);
}
void
@@ -481,6 +487,24 @@ ResolveTypeToCanonicalPath::visit (AST::TypePathSegment &seg)
result = result.append (ident_seg);
}
+void
+ResolveTypeToCanonicalPath::visit (AST::ReferenceType &ref)
+{
+ auto inner_type
+ = ResolveTypeToCanonicalPath::resolve (*ref.get_type_referenced ().get (),
+ include_generic_args_flag,
+ type_resolve_generic_args_flag);
+
+ std::string segment_string ("&");
+ if (ref.get_has_mut ())
+ segment_string += "mut ";
+
+ segment_string += inner_type.get ();
+
+ auto ident_seg = CanonicalPath::new_seg (ref.get_node_id (), segment_string);
+ result = result.append (ident_seg);
+}
+
// rust-ast-resolve-expr.h
void
diff --git a/gcc/rust/resolve/rust-ast-verify-assignee.h b/gcc/rust/resolve/rust-ast-verify-assignee.h
index 6fbf5fe..d362fe4 100644
--- a/gcc/rust/resolve/rust-ast-verify-assignee.h
+++ b/gcc/rust/resolve/rust-ast-verify-assignee.h
@@ -75,6 +75,13 @@ public:
}
}
+ void visit (AST::DereferenceExpr &expr) override
+ {
+ expr.get_dereferenced_expr ()->accept_vis (*this);
+ }
+
+ void visit (AST::PathInExpression &expr) override { ok = true; }
+
private:
VerifyAsignee (NodeId parent) : ResolverBase (parent), ok (false) {}
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index 705f7dc..64144bc 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -29,6 +29,8 @@
#include "operator.h"
#include "rust-abi.h"
+#include "tree.h"
+
extern bool
saw_errors (void);
@@ -39,27 +41,9 @@ saw_errors (void);
// frontend, and passed back to the backend. The types must be
// defined by the backend using these names.
-// The backend representation of a type.
-class Btype;
-
-// The backend represention of an expression.
-class Bexpression;
-
-// The backend representation of a statement.
-class Bstatement;
-
-// The backend representation of a function definition or declaration.
-class Bfunction;
-
-// The backend representation of a block.
-class Bblock;
-
// The backend representation of a variable.
class Bvariable;
-// The backend representation of a label.
-class Blabel;
-
// The backend interface. This is a pure abstract class that a
// specific backend will implement.
@@ -70,35 +54,30 @@ public:
// Name/type/location. Used for function parameters, struct fields,
// interface methods.
- struct Btyped_identifier
+ struct typed_identifier
{
std::string name;
- Btype *btype;
+ tree type;
Location location;
- Btyped_identifier ()
- : name (), btype (NULL), location (Linemap::unknown_location ())
+ typed_identifier ()
+ : name (), type (NULL_TREE), location (Linemap::unknown_location ())
{}
- Btyped_identifier (const std::string &a_name, Btype *a_btype,
- Location a_location)
- : name (a_name), btype (a_btype), location (a_location)
+ typed_identifier (const std::string &a_name, tree a_type,
+ Location a_location)
+ : name (a_name), type (a_type), location (a_location)
{}
};
// debug
- virtual void debug (Btype *) = 0;
- virtual void debug (Bexpression *) = 0;
- virtual void debug (Bstatement *) = 0;
- virtual void debug (Bfunction *) = 0;
- virtual void debug (Bblock *) = 0;
+ virtual void debug (tree) = 0;
virtual void debug (Bvariable *) = 0;
- virtual void debug (Blabel *) = 0;
// const folder helpers
- virtual bool const_size_cast (Bexpression *, size_t *) = 0;
- virtual std::string const_size_val_to_string (Bexpression *) = 0;
- virtual bool const_values_equal (Bexpression *, Bexpression *) = 0;
+ virtual bool const_size_cast (tree, size_t *) = 0;
+ virtual std::string const_size_val_to_string (tree) = 0;
+ virtual bool const_values_equal (tree, tree) = 0;
static Rust::ABI get_abi_from_string (const std::string &abi, Location locus)
{
@@ -147,50 +126,50 @@ public:
// Produce an error type. Actually the backend could probably just
// crash if this is called.
- virtual Btype *error_type () = 0;
+ virtual tree error_type () = 0;
// Get a void type. This is used in (at least) two ways: 1) as the
// return type of a function with no result parameters; 2)
// unsafe.Pointer is represented as *void.
- virtual Btype *void_type () = 0;
+ virtual tree void_type () = 0;
// get unit-type
- virtual Btype *unit_type () = 0;
+ virtual tree unit_type () = 0;
// Get the unnamed boolean type.
- virtual Btype *bool_type () = 0;
+ virtual tree bool_type () = 0;
// Get the char type
- virtual Btype *char_type () = 0;
+ virtual tree char_type () = 0;
// Get the wchar type
- virtual Btype *wchar_type () = 0;
+ virtual tree wchar_type () = 0;
// Get the Host pointer size in bits
virtual int get_pointer_size () = 0;
// Get the raw str type const char*
- virtual Btype *raw_str_type () = 0;
+ virtual tree raw_str_type () = 0;
// Get an unnamed integer type with the given signedness and number
// of bits.
- virtual Btype *integer_type (bool is_unsigned, int bits) = 0;
+ virtual tree integer_type (bool is_unsigned, int bits) = 0;
// Get an unnamed floating point type with the given number of bits
// (32 or 64).
- virtual Btype *float_type (int bits) = 0;
+ virtual tree float_type (int bits) = 0;
// Get an unnamed complex type with the given number of bits (64 or 128).
- virtual Btype *complex_type (int bits) = 0;
+ virtual tree complex_type (int bits) = 0;
// Get a pointer type.
- virtual Btype *pointer_type (Btype *to_type) = 0;
+ virtual tree pointer_type (tree to_type) = 0;
// Get a reference type.
- virtual Btype *reference_type (Btype *to_type) = 0;
+ virtual tree reference_type (tree to_type) = 0;
// make type immutable
- virtual Btype *immutable_type (Btype *base) = 0;
+ virtual tree immutable_type (tree base) = 0;
// Get a function type. The receiver, parameter, and results are
// generated from the types in the Function_type. The Function_type
@@ -201,305 +180,201 @@ public:
// one result, RESULT_STRUCT is a struct type to hold the results,
// and RESULTS may be ignored; if there are zero or one results,
// RESULT_STRUCT is NULL.
- virtual Btype *
- function_type (const Btyped_identifier &receiver,
- const std::vector<Btyped_identifier> &parameters,
- const std::vector<Btyped_identifier> &results,
- Btype *result_struct, Location location)
+ virtual tree function_type (const typed_identifier &receiver,
+ const std::vector<typed_identifier> &parameters,
+ const std::vector<typed_identifier> &results,
+ tree result_struct, Location location)
= 0;
- virtual Btype *
- function_type_varadic (const Btyped_identifier &receiver,
- const std::vector<Btyped_identifier> &parameters,
- const std::vector<Btyped_identifier> &results,
- Btype *result_struct, Location location)
+ virtual tree
+ function_type_varadic (const typed_identifier &receiver,
+ const std::vector<typed_identifier> &parameters,
+ const std::vector<typed_identifier> &results,
+ tree result_struct, Location location)
= 0;
- virtual Btype *function_ptr_type (Btype *result,
- const std::vector<Btype *> &praameters,
- Location location)
+ virtual tree function_ptr_type (tree result,
+ const std::vector<tree> &praameters,
+ Location location)
= 0;
// Get a struct type.
- virtual Btype *struct_type (const std::vector<Btyped_identifier> &fields) = 0;
+ virtual tree struct_type (const std::vector<typed_identifier> &fields) = 0;
// Get a union type.
- virtual Btype *union_type (const std::vector<Btyped_identifier> &fields) = 0;
+ virtual tree union_type (const std::vector<typed_identifier> &fields) = 0;
// Get an array type.
- virtual Btype *array_type (Btype *element_type, Bexpression *length) = 0;
-
- // Create a placeholder pointer type. This is used for a named
- // pointer type, since in Go a pointer type may refer to itself.
- // NAME is the name of the type, and the location is where the named
- // type is defined. This function is also used for unnamed function
- // types with multiple results, in which case the type has no name
- // and NAME will be empty. FOR_FUNCTION is true if this is for a C
- // pointer to function type. A Go func type is represented as a
- // pointer to a struct, and the first field of the struct is a C
- // pointer to function. The return value will later be passed as
- // the first parameter to set_placeholder_pointer_type or
- // set_placeholder_function_type.
- virtual Btype *placeholder_pointer_type (const std::string &name, Location,
- bool for_function)
- = 0;
-
- // Fill in a placeholder pointer type as a pointer. This takes a
- // type returned by placeholder_pointer_type and arranges for it to
- // point to the type that TO_TYPE points to (that is, PLACEHOLDER
- // becomes the same type as TO_TYPE). Returns true on success,
- // false on failure.
- virtual bool set_placeholder_pointer_type (Btype *placeholder, Btype *to_type)
- = 0;
-
- // Fill in a placeholder pointer type as a function. This takes a
- // type returned by placeholder_pointer_type and arranges for it to
- // become a real Go function type (which corresponds to a C/C++
- // pointer to function type). FT will be something returned by the
- // function_type method. Returns true on success, false on failure.
- virtual bool set_placeholder_function_type (Btype *placeholder, Btype *ft)
- = 0;
-
- // Create a placeholder struct type. This is used for a named
- // struct type, as with placeholder_pointer_type. It is also used
- // for interface types, in which case NAME will be the empty string.
- virtual Btype *placeholder_struct_type (const std::string &name, Location)
- = 0;
-
- // Fill in a placeholder struct type. This takes a type returned by
- // placeholder_struct_type and arranges for it to become a real
- // struct type. The parameter is as for struct_type. Returns true
- // on success, false on failure.
- virtual bool
- set_placeholder_struct_type (Btype *placeholder,
- const std::vector<Btyped_identifier> &fields)
- = 0;
-
- // Create a placeholder array type. This is used for a named array
- // type, as with placeholder_pointer_type, to handle cases like
- // type A []*A.
- virtual Btype *placeholder_array_type (const std::string &name, Location) = 0;
-
- // Fill in a placeholder array type. This takes a type returned by
- // placeholder_array_type and arranges for it to become a real array
- // type. The parameters are as for array_type. Returns true on
- // success, false on failure.
- virtual bool set_placeholder_array_type (Btype *placeholder,
- Btype *element_type,
- Bexpression *length)
- = 0;
+ virtual tree array_type (tree element_type, tree length) = 0;
// Return a named version of a type. The location is the location
// of the type definition. This will not be called for a type
// created via placeholder_pointer_type, placeholder_struct_type, or
// placeholder_array_type.. (It may be called for a pointer,
// struct, or array type in a case like "type P *byte; type Q P".)
- virtual Btype *named_type (const std::string &name, Btype *, Location) = 0;
-
- // Create a marker for a circular pointer type. Go pointer and
- // function types can refer to themselves in ways that are not
- // permitted in C/C++. When a circular type is found, this function
- // is called for the circular reference. This permits the backend
- // to decide how to handle such a type. PLACEHOLDER is the
- // placeholder type which has already been created; if the backend
- // is prepared to handle a circular pointer type, it may simply
- // return PLACEHOLDER. FOR_FUNCTION is true if this is for a
- // function type.
- //
- // For "type P *P" the sequence of calls will be
- // bt1 = placeholder_pointer_type();
- // bt2 = circular_pointer_type(bt1, false);
- // set_placeholder_pointer_type(bt1, bt2);
- virtual Btype *circular_pointer_type (Btype *placeholder, bool for_function)
- = 0;
-
- // Return whether the argument could be a special type created by
- // circular_pointer_type. This is used to introduce explicit type
- // conversions where needed. If circular_pointer_type returns its
- // PLACEHOLDER parameter, this may safely always return false.
- virtual bool is_circular_pointer_type (Btype *) = 0;
+ virtual tree named_type (const std::string &name, tree, Location) = 0;
// Return the size of a type.
- virtual int64_t type_size (Btype *) = 0;
+ virtual int64_t type_size (tree) = 0;
// Return the alignment of a type.
- virtual int64_t type_alignment (Btype *) = 0;
+ virtual int64_t type_alignment (tree) = 0;
// Return the alignment of a struct field of this type. This is
// normally the same as type_alignment, but not always.
- virtual int64_t type_field_alignment (Btype *) = 0;
+ virtual int64_t type_field_alignment (tree) = 0;
// Return the offset of field INDEX in a struct type. INDEX is the
// entry in the FIELDS std::vector parameter of struct_type or
// set_placeholder_struct_type.
- virtual int64_t type_field_offset (Btype *, size_t index) = 0;
+ virtual int64_t type_field_offset (tree, size_t index) = 0;
// Expressions.
// Return an expression for a zero value of the given type. This is
// used for cases such as local variable initialization and
// converting nil to other types.
- virtual Bexpression *zero_expression (Btype *) = 0;
+ virtual tree zero_expression (tree) = 0;
// Create an error expression. This is used for cases which should
// not occur in a correct program, in order to keep the compilation
// going without crashing.
- virtual Bexpression *error_expression () = 0;
+ virtual tree error_expression () = 0;
// return whether this is error_mark_node
- virtual bool is_error_expression (Bexpression *) = 0;
+ virtual bool is_error_expression (tree) = 0;
// Create a nil pointer expression.
- virtual Bexpression *nil_pointer_expression () = 0;
+ virtual tree nil_pointer_expression () = 0;
- virtual Bexpression *unit_expression () = 0;
+ virtual tree unit_expression () = 0;
// Create a reference to a variable.
- virtual Bexpression *var_expression (Bvariable *var, Location) = 0;
+ virtual tree var_expression (Bvariable *var, Location) = 0;
// Create an expression that indirects through the pointer expression EXPR
// (i.e., return the expression for *EXPR). KNOWN_VALID is true if the pointer
// is known to point to a valid memory location. BTYPE is the expected type
// of the indirected EXPR.
- virtual Bexpression *indirect_expression (Btype *btype, Bexpression *expr,
- bool known_valid, Location)
+ virtual tree indirect_expression (tree btype, tree expr, bool known_valid,
+ Location)
= 0;
// Return an expression that declares a constant named NAME with the
// constant value VAL in BTYPE.
- virtual Bexpression *named_constant_expression (Btype *btype,
- const std::string &name,
- Bexpression *val, Location)
+ virtual tree named_constant_expression (tree btype, const std::string &name,
+ tree val, Location)
= 0;
// Return an expression for the multi-precision integer VAL in BTYPE.
- virtual Bexpression *integer_constant_expression (Btype *btype, mpz_t val)
- = 0;
+ virtual tree integer_constant_expression (tree btype, mpz_t val) = 0;
// Return an expression for the floating point value VAL in BTYPE.
- virtual Bexpression *float_constant_expression (Btype *btype, mpfr_t val) = 0;
+ virtual tree float_constant_expression (tree btype, mpfr_t val) = 0;
// Return an expression for the complex value VAL in BTYPE.
- virtual Bexpression *complex_constant_expression (Btype *btype, mpc_t val)
- = 0;
+ virtual tree complex_constant_expression (tree btype, mpc_t val) = 0;
// Return an expression for the string value VAL.
- virtual Bexpression *string_constant_expression (const std::string &val) = 0;
+ virtual tree string_constant_expression (const std::string &val) = 0;
// Get a char literal
- virtual Bexpression *char_constant_expression (char c) = 0;
+ virtual tree char_constant_expression (char c) = 0;
// Get a char literal
- virtual Bexpression *wchar_constant_expression (wchar_t c) = 0;
+ virtual tree wchar_constant_expression (wchar_t c) = 0;
// Return an expression for the boolean value VAL.
- virtual Bexpression *boolean_constant_expression (bool val) = 0;
+ virtual tree boolean_constant_expression (bool val) = 0;
// Return an expression for the real part of BCOMPLEX.
- virtual Bexpression *real_part_expression (Bexpression *bcomplex, Location)
- = 0;
+ virtual tree real_part_expression (tree bcomplex, Location) = 0;
// Return an expression for the imaginary part of BCOMPLEX.
- virtual Bexpression *imag_part_expression (Bexpression *bcomplex, Location)
- = 0;
+ virtual tree imag_part_expression (tree bcomplex, Location) = 0;
// Return an expression for the complex number (BREAL, BIMAG).
- virtual Bexpression *complex_expression (Bexpression *breal,
- Bexpression *bimag, Location)
- = 0;
+ virtual tree complex_expression (tree breal, tree bimag, Location) = 0;
// Return an expression that converts EXPR to TYPE.
- virtual Bexpression *convert_expression (Btype *type, Bexpression *expr,
- Location)
- = 0;
+ virtual tree convert_expression (tree type, tree expr, Location) = 0;
// Create an expression for the address of a function. This is used to
// get the address of the code for a function.
- virtual Bexpression *function_code_expression (Bfunction *, Location) = 0;
+ virtual tree function_code_expression (tree, Location) = 0;
// Create an expression that takes the address of an expression.
- virtual Bexpression *address_expression (Bexpression *, Location) = 0;
+ virtual tree address_expression (tree, Location) = 0;
// Return an expression for the field at INDEX in BSTRUCT.
- virtual Bexpression *struct_field_expression (Bexpression *bstruct,
- size_t index, Location)
+ virtual tree struct_field_expression (tree bstruct, size_t index, Location)
= 0;
// Create an expression that executes BSTAT before BEXPR.
- virtual Bexpression *compound_expression (Bstatement *bstat,
- Bexpression *bexpr, Location)
- = 0;
+ virtual tree compound_expression (tree bstat, tree bexpr, Location) = 0;
// Return an expression that executes THEN_EXPR if CONDITION is true, or
// ELSE_EXPR otherwise and returns the result as type BTYPE, within the
// specified function FUNCTION. ELSE_EXPR may be NULL. BTYPE may be NULL.
- virtual Bexpression *
- conditional_expression (Bfunction *function, Btype *btype,
- Bexpression *condition, Bexpression *then_expr,
- Bexpression *else_expr, Location)
+ virtual tree conditional_expression (tree function, tree btype,
+ tree condition, tree then_expr,
+ tree else_expr, Location)
= 0;
// Return an expression for the negation operation OP EXPR.
// Supported values of OP are enumerated in NegationOperator.
- virtual Bexpression *negation_expression (NegationOperator op,
- Bexpression *expr, Location)
+ virtual tree negation_expression (NegationOperator op, tree expr, Location)
= 0;
// Return an expression for the operation LEFT OP RIGHT.
// Supported values of OP are enumerated in ArithmeticOrLogicalOperator.
- virtual Bexpression *
- arithmetic_or_logical_expression (ArithmeticOrLogicalOperator op,
- Bexpression *left, Bexpression *right,
- Location)
+ virtual tree arithmetic_or_logical_expression (ArithmeticOrLogicalOperator op,
+ tree left, tree right,
+ Location)
= 0;
// Return an expression for the operation LEFT OP RIGHT.
// Supported values of OP are enumerated in ComparisonOperator.
- virtual Bexpression *comparison_expression (ComparisonOperator op,
- Bexpression *left,
- Bexpression *right, Location)
+ virtual tree comparison_expression (ComparisonOperator op, tree left,
+ tree right, Location)
= 0;
// Return an expression for the operation LEFT OP RIGHT.
// Supported values of OP are enumerated in LazyBooleanOperator.
- virtual Bexpression *lazy_boolean_expression (LazyBooleanOperator op,
- Bexpression *left,
- Bexpression *right, Location)
+ virtual tree lazy_boolean_expression (LazyBooleanOperator op, tree left,
+ tree right, Location)
= 0;
// Return an expression that constructs BTYPE with VALS. BTYPE must be the
// backend representation a of struct. VALS must be in the same order as the
// corresponding fields in BTYPE.
- virtual Bexpression *
- constructor_expression (Btype *btype, const std::vector<Bexpression *> &vals,
- int, Location)
+ virtual tree constructor_expression (tree btype,
+ const std::vector<tree> &vals, int,
+ Location)
= 0;
// Return an expression that constructs an array of BTYPE with INDEXES and
// VALS. INDEXES and VALS must have the same amount of elements. Each index
// in INDEXES must be in the same order as the corresponding value in VALS.
- virtual Bexpression *array_constructor_expression (
- Btype *btype, const std::vector<unsigned long> &indexes,
- const std::vector<Bexpression *> &vals, Location)
+ virtual tree
+ array_constructor_expression (tree btype,
+ const std::vector<unsigned long> &indexes,
+ const std::vector<tree> &vals, Location)
= 0;
// Return an expression for the address of BASE[INDEX].
// BASE has a pointer type. This is used for slice indexing.
- virtual Bexpression *pointer_offset_expression (Bexpression *base,
- Bexpression *index, Location)
- = 0;
+ virtual tree pointer_offset_expression (tree base, tree index, Location) = 0;
// Return an expression for ARRAY[INDEX] as an l-value. ARRAY is a valid
// fixed-length array, not a slice.
- virtual Bexpression *array_index_expression (Bexpression *array,
- Bexpression *index, Location)
- = 0;
+ virtual tree array_index_expression (tree array, tree index, Location) = 0;
// Create an expression for a call to FN with ARGS, taking place within
// caller CALLER.
- virtual Bexpression *call_expression (Bfunction *caller, Bexpression *fn,
- const std::vector<Bexpression *> &args,
- Bexpression *static_chain, Location)
+ virtual tree call_expression (tree caller, tree fn,
+ const std::vector<tree> &args,
+ tree static_chain, Location)
= 0;
// Statements.
@@ -507,40 +382,33 @@ public:
// Create an error statement. This is used for cases which should
// not occur in a correct program, in order to keep the compilation
// going without crashing.
- virtual Bstatement *error_statement () = 0;
+ virtual tree error_statement () = 0;
// Create an expression statement within the specified function.
- virtual Bstatement *expression_statement (Bfunction *, Bexpression *) = 0;
+ virtual tree expression_statement (tree, tree) = 0;
// Create a variable initialization statement in the specified
// function. This initializes a local variable at the point in the
// program flow where it is declared.
- virtual Bstatement *init_statement (Bfunction *, Bvariable *var,
- Bexpression *init)
- = 0;
+ virtual tree init_statement (tree, Bvariable *var, tree init) = 0;
// Create an assignment statement within the specified function.
- virtual Bstatement *assignment_statement (Bfunction *, Bexpression *lhs,
- Bexpression *rhs, Location)
- = 0;
+ virtual tree assignment_statement (tree, tree lhs, tree rhs, Location) = 0;
// Create a return statement, passing the representation of the
// function and the list of values to return.
- virtual Bstatement *
- return_statement (Bfunction *, const std::vector<Bexpression *> &, Location)
- = 0;
+ virtual tree return_statement (tree, const std::vector<tree> &, Location) = 0;
// Create an if statement within a function. ELSE_BLOCK may be NULL.
- virtual Bstatement *if_statement (Bfunction *, Bexpression *condition,
- Bblock *then_block, Bblock *else_block,
- Location)
+ virtual tree if_statement (tree, tree condition, tree then_block,
+ tree else_block, Location)
= 0;
// infinite loop expressions
- virtual Bexpression *loop_expression (Bblock *body, Location) = 0;
+ virtual tree loop_expression (tree body, Location) = 0;
// exit expressions
- virtual Bexpression *exit_expression (Bexpression *condition, Location) = 0;
+ virtual tree exit_expression (tree condition, Location) = 0;
// Create a switch statement where the case values are constants.
// CASES and STATEMENTS must have the same number of entries. If
@@ -549,26 +417,24 @@ public:
// either end with a goto statement or will fall through into
// STATEMENTS[i + 1]. CASES[i] is empty for the default clause,
// which need not be last. FUNCTION is the current function.
- virtual Bstatement *
- switch_statement (Bfunction *function, Bexpression *value,
- const std::vector<std::vector<Bexpression *> > &cases,
- const std::vector<Bstatement *> &statements, Location)
+ virtual tree switch_statement (tree function, tree value,
+ const std::vector<std::vector<tree> > &cases,
+ const std::vector<tree> &statements, Location)
= 0;
// Create a single statement from two statements.
- virtual Bstatement *compound_statement (Bstatement *, Bstatement *) = 0;
+ virtual tree compound_statement (tree, tree) = 0;
// Create a single statement from a list of statements.
- virtual Bstatement *statement_list (const std::vector<Bstatement *> &) = 0;
+ virtual tree statement_list (const std::vector<tree> &) = 0;
// Create a statement that attempts to execute BSTAT and calls EXCEPT_STMT if
// an exception occurs. EXCEPT_STMT may be NULL. FINALLY_STMT may be NULL and
// if not NULL, it will always be executed. This is used for handling defers
// in Go functions. In C++, the resulting code is of this form:
// try { BSTAT; } catch { EXCEPT_STMT; } finally { FINALLY_STMT; }
- virtual Bstatement *
- exception_handler_statement (Bstatement *bstat, Bstatement *except_stmt,
- Bstatement *finally_stmt, Location)
+ virtual tree exception_handler_statement (tree bstat, tree except_stmt,
+ tree finally_stmt, Location)
= 0;
// Blocks.
@@ -583,22 +449,20 @@ public:
// the initial curly brace. END_LOCATION is the location of the end
// of the block, more or less the location of the final curly brace.
// The statements will be added after the block is created.
- virtual Bblock *block (Bfunction *function, Bblock *enclosing,
- const std::vector<Bvariable *> &vars,
- Location start_location, Location end_location)
+ virtual tree block (tree function, tree enclosing,
+ const std::vector<Bvariable *> &vars,
+ Location start_location, Location end_location)
= 0;
// Add the statements to a block. The block is created first. Then
// the statements are created. Then the statements are added to the
// block. This will called exactly once per block. The vector may
// be empty if there are no statements.
- virtual void block_add_statements (Bblock *,
- const std::vector<Bstatement *> &)
- = 0;
+ virtual void block_add_statements (tree, const std::vector<tree> &) = 0;
// Return the block as a statement. This is used to include a block
// in a list of statements.
- virtual Bstatement *block_statement (Bblock *) = 0;
+ virtual tree block_statement (tree) = 0;
// Variables.
@@ -618,7 +482,7 @@ public:
// permit the linker to garbage collect the variable if it is not
// referenced. LOCATION is where the variable was defined.
virtual Bvariable *global_variable (const std::string &name,
- const std::string &asm_name, Btype *btype,
+ const std::string &asm_name, tree btype,
bool is_external, bool is_hidden,
bool in_unique_section, Location location)
= 0;
@@ -629,7 +493,7 @@ public:
// global_variable_set_init to set the initial value. If this is
// not called, the backend should initialize a global variable to 0.
// The init function may then assign a value to it.
- virtual void global_variable_set_init (Bvariable *, Bexpression *) = 0;
+ virtual void global_variable_set_init (Bvariable *, tree) = 0;
// Create a local variable. The frontend will create the local
// variables first, and then create the block which contains them.
@@ -643,23 +507,23 @@ public:
// the function, as otherwise the variable would be on the heap).
// LOCATION is where the variable is defined. For each local variable
// the frontend will call init_statement to set the initial value.
- virtual Bvariable *
- local_variable (Bfunction *function, const std::string &name, Btype *type,
- Bvariable *decl_var, bool is_address_taken, Location location)
+ virtual Bvariable *local_variable (tree function, const std::string &name,
+ tree type, Bvariable *decl_var,
+ bool is_address_taken, Location location)
= 0;
// Create a function parameter. This is an incoming parameter, not
// a result parameter (result parameters are treated as local
// variables). The arguments are as for local_variable.
- virtual Bvariable *
- parameter_variable (Bfunction *function, const std::string &name, Btype *type,
- bool is_address_taken, Location location)
+ virtual Bvariable *parameter_variable (tree function, const std::string &name,
+ tree type, bool is_address_taken,
+ Location location)
= 0;
// Create a static chain parameter. This is the closure parameter.
- virtual Bvariable *static_chain_variable (Bfunction *function,
- const std::string &name,
- Btype *type, Location location)
+ virtual Bvariable *static_chain_variable (tree function,
+ const std::string &name, tree type,
+ Location location)
= 0;
// Create a temporary variable. A temporary variable has no name,
@@ -673,10 +537,9 @@ public:
// variable, and may not be very useful. This function should
// return a variable which can be referenced later and should set
// *PSTATEMENT to a statement which initializes the variable.
- virtual Bvariable *
- temporary_variable (Bfunction *, Bblock *, Btype *, Bexpression *init,
- bool address_is_taken, Location location,
- Bstatement **pstatement)
+ virtual Bvariable *temporary_variable (tree, tree, tree, tree init,
+ bool address_is_taken,
+ Location location, tree *pstatement)
= 0;
// Create an implicit variable that is compiler-defined. This is
@@ -705,10 +568,10 @@ public:
// the zero value. IS_HIDDEN and IS_COMMON will never both be true.
//
// If ALIGNMENT is not zero, it is the desired alignment of the variable.
- virtual Bvariable *
- implicit_variable (const std::string &name, const std::string &asm_name,
- Btype *type, bool is_hidden, bool is_constant,
- bool is_common, int64_t alignment)
+ virtual Bvariable *implicit_variable (const std::string &name,
+ const std::string &asm_name, tree type,
+ bool is_hidden, bool is_constant,
+ bool is_common, int64_t alignment)
= 0;
// Set the initial value of a variable created by implicit_variable.
@@ -722,9 +585,9 @@ public:
// If IS_COMMON is true, INIT will be NULL, and the
// variable should be initialized to all zeros.
virtual void implicit_variable_set_init (Bvariable *, const std::string &name,
- Btype *type, bool is_hidden,
+ tree type, bool is_hidden,
bool is_constant, bool is_common,
- Bexpression *init)
+ tree init)
= 0;
// Create a reference to a named implicit variable defined in some
@@ -734,7 +597,7 @@ public:
// variable in C.
virtual Bvariable *implicit_variable_reference (const std::string &name,
const std::string &asm_name,
- Btype *type)
+ tree type)
= 0;
// Create a named immutable initialized data structure. This is
@@ -767,7 +630,7 @@ public:
// immutable_struct_set_init.
virtual Bvariable *
immutable_struct (const std::string &name, const std::string &asm_name,
- bool is_hidden, bool is_common, Btype *type, Location)
+ bool is_hidden, bool is_common, tree type, Location)
= 0;
// Set the initial value of a variable created by immutable_struct.
@@ -779,8 +642,7 @@ public:
// immutable_struct.
virtual void immutable_struct_set_init (Bvariable *, const std::string &name,
bool is_hidden, bool is_common,
- Btype *type, Location,
- Bexpression *initializer)
+ tree type, Location, tree initializer)
= 0;
// Create a reference to a named immutable initialized data
@@ -790,7 +652,7 @@ public:
// corresponds to an extern const global variable in C.
virtual Bvariable *immutable_struct_reference (const std::string &name,
const std::string &asm_name,
- Btype *type, Location)
+ tree type, Location)
= 0;
// Labels.
@@ -798,27 +660,27 @@ public:
// Create a new label. NAME will be empty if this is a label
// created by the frontend for a loop construct. The location is
// where the label is defined.
- virtual Blabel *label (Bfunction *, const std::string &name, Location) = 0;
+ virtual tree label (tree, const std::string &name, Location) = 0;
// Create a statement which defines a label. This statement will be
// put into the codestream at the point where the label should be
// defined.
- virtual Bstatement *label_definition_statement (Blabel *) = 0;
+ virtual tree label_definition_statement (tree) = 0;
// Create a goto statement to a label.
- virtual Bstatement *goto_statement (Blabel *, Location) = 0;
+ virtual tree goto_statement (tree, Location) = 0;
// Create an expression for the address of a label. This is used to
// get the return address of a deferred function which may call
// recover.
- virtual Bexpression *label_address (Blabel *, Location) = 0;
+ virtual tree label_address (tree, Location) = 0;
// Functions.
// Create an error function. This is used for cases which should
// not occur in a correct program, in order to keep the compilation
// going without crashing.
- virtual Bfunction *error_function () = 0;
+ virtual tree error_function () = 0;
// Bit flags to pass to the function method.
@@ -857,49 +719,47 @@ public:
// string, is the name that should be used in the symbol table; this
// will be non-empty if a magic extern comment is used. FLAGS is
// bit flags described above.
- virtual Bfunction *function (Btype *fntype, const std::string &name,
- const std::string &asm_name, unsigned int flags,
- Location)
+ virtual tree function (tree fntype, const std::string &name,
+ const std::string &asm_name, unsigned int flags,
+ Location)
= 0;
- virtual Btype *specify_abi_attribute (Btype *type, Rust::ABI abi) = 0;
+ virtual tree specify_abi_attribute (tree type, Rust::ABI abi) = 0;
// Create a statement that runs all deferred calls for FUNCTION. This should
// be a statement that looks like this in C++:
// finish:
// try { DEFER_RETURN; } catch { CHECK_DEFER; goto finish; }
- virtual Bstatement *
- function_defer_statement (Bfunction *function, Bexpression *undefer,
- Bexpression *check_defer, Location)
+ virtual tree function_defer_statement (tree function, tree undefer,
+ tree check_defer, Location)
= 0;
// Record PARAM_VARS as the variables to use for the parameters of FUNCTION.
// This will only be called for a function definition. Returns true on
// success, false on failure.
virtual bool
- function_set_parameters (Bfunction *function,
+ function_set_parameters (tree function,
const std::vector<Bvariable *> &param_vars)
= 0;
// Set the function body for FUNCTION using the code in CODE_STMT. Returns
// true on success, false on failure.
- virtual bool function_set_body (Bfunction *function, Bstatement *code_stmt)
- = 0;
+ virtual bool function_set_body (tree function, tree code_stmt) = 0;
// Look up a named built-in function in the current backend implementation.
// Returns NULL if no built-in function by that name exists.
- virtual Bfunction *lookup_gcc_builtin (const std::string &) = 0;
+ virtual tree lookup_gcc_builtin (const std::string &) = 0;
- virtual Bfunction *lookup_builtin_by_rust_name (const std::string &) = 0;
+ virtual tree lookup_builtin_by_rust_name (const std::string &) = 0;
// Utility.
// Write the definitions for all TYPE_DECLS, CONSTANT_DECLS,
// FUNCTION_DECLS, and VARIABLE_DECLS declared globally.
virtual void
- write_global_definitions (const std::vector<Btype *> &type_decls,
- const std::vector<Bexpression *> &constant_decls,
- const std::vector<Bfunction *> &function_decls,
+ write_global_definitions (const std::vector<tree> &type_decls,
+ const std::vector<tree> &constant_decls,
+ const std::vector<tree> &function_decls,
const std::vector<Bvariable *> &variable_decls)
= 0;
diff --git a/gcc/rust/rust-diagnostics.h b/gcc/rust/rust-diagnostics.h
index d9461f1..1c2ec84 100644
--- a/gcc/rust/rust-diagnostics.h
+++ b/gcc/rust/rust-diagnostics.h
@@ -48,6 +48,7 @@
// All other format specifiers are as defined by 'sprintf'. The final resulting
// message is then sent to the back end via rust_be_error_at/rust_be_warning_at.
+// clang-format off
// simple location
extern void
rust_internal_error_at (const Location, const char *fmt, ...)
@@ -71,6 +72,7 @@ rust_inform (const Location, const char *fmt, ...)
extern void
rust_error_at (const RichLocation &, const char *fmt, ...)
RUST_ATTRIBUTE_GCC_DIAG (2, 3);
+// clang-format on
// These interfaces provide a way for the front end to ask for
// the open/close quote characters it should use when formatting
@@ -86,6 +88,7 @@ rust_close_quote ();
// instead use the equivalent routines above. The back end is required to
// implement these routines.
+// clang-format off
extern void
rust_be_internal_error_at (const Location, const std::string &errmsg)
RUST_ATTRIBUTE_NORETURN;
@@ -104,6 +107,7 @@ extern void
rust_be_get_quotechars (const char **open_quote, const char **close_quote);
extern bool
rust_be_debug_p (void);
+// clang-format on
namespace Rust {
/* A structure used to represent an error. Useful for enabling
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index efc7823..12df769 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -53,58 +53,6 @@
// TODO: this will have to be significantly modified to work with Rust
-// A class wrapping a tree.
-
-class Gcc_tree
-{
-public:
- Gcc_tree (tree t) : t_ (t) {}
-
- tree get_tree () const { return this->t_; }
-
- void set_tree (tree t) { this->t_ = t; }
-
-private:
- tree t_;
-};
-
-// In gcc, types, expressions, and statements are all trees.
-class Btype : public Gcc_tree
-{
-public:
- Btype (tree t) : Gcc_tree (t) {}
-};
-
-class Bexpression : public Gcc_tree
-{
-public:
- Bexpression (tree t) : Gcc_tree (t) {}
-};
-
-class Bstatement : public Gcc_tree
-{
-public:
- Bstatement (tree t) : Gcc_tree (t) {}
-};
-
-class Bfunction : public Gcc_tree
-{
-public:
- Bfunction (tree t) : Gcc_tree (t) {}
-};
-
-class Bblock : public Gcc_tree
-{
-public:
- Bblock (tree t) : Gcc_tree (t) {}
-};
-
-class Blabel : public Gcc_tree
-{
-public:
- Blabel (tree t) : Gcc_tree (t) {}
-};
-
// Bvariable is a bit more complicated, because of zero-sized types.
// The GNU linker does not permit dynamic variables with zero size.
// When we see such a variable, we generate a version of the type with
@@ -159,22 +107,17 @@ class Gcc_backend : public Backend
public:
Gcc_backend ();
- void debug (Btype *t) { debug_tree (t->get_tree ()); };
- void debug (Bexpression *t) { debug_tree (t->get_tree ()); };
- void debug (Bstatement *t) { debug_tree (t->get_tree ()); };
- void debug (Bfunction *t) { debug_tree (t->get_tree ()); };
- void debug (Bblock *t) { debug_tree (t->get_tree ()); };
+ void debug (tree t) { debug_tree (t); };
void debug (Bvariable *t) { debug_tree (t->get_decl ()); };
- void debug (Blabel *t) { debug_tree (t->get_tree ()); };
// Types.
- Btype *error_type () { return this->make_type (error_mark_node); }
+ tree error_type () { return error_mark_node; }
- Btype *void_type () { return this->make_type (void_type_node); }
+ tree void_type () { return void_type_node; }
- Btype *unit_type ()
+ tree unit_type ()
{
- static Btype *unit_type;
+ static tree unit_type;
if (unit_type == nullptr)
{
auto unit_type_node = integer_type (true, 0);
@@ -185,18 +128,18 @@ public:
return unit_type;
}
- Btype *bool_type () { return this->make_type (boolean_type_node); }
+ tree bool_type () { return boolean_type_node; }
- Btype *char_type () { return this->make_type (char_type_node); }
+ tree char_type () { return char_type_node; }
- bool const_size_cast (Bexpression *expr, size_t *result)
+ bool const_size_cast (tree expr, size_t *result)
{
- rust_assert (TREE_CONSTANT (expr->get_tree ()));
+ rust_assert (TREE_CONSTANT (expr));
unsigned char buf[sizeof (size_t) + 1];
memset (buf, 0, sizeof (buf));
- int ret = native_encode_expr (expr->get_tree (), buf, sizeof (buf), 0);
+ int ret = native_encode_expr (expr, buf, sizeof (buf), 0);
if (ret <= 0)
return false;
@@ -205,344 +148,276 @@ public:
return true;
}
- std::string const_size_val_to_string (Bexpression *expr)
+ std::string const_size_val_to_string (tree expr)
{
- rust_assert (TREE_CONSTANT (expr->get_tree ()));
+ rust_assert (TREE_CONSTANT (expr));
unsigned char buf[sizeof (size_t) + 1];
memset (buf, 0, sizeof (buf));
- int ret = native_encode_expr (expr->get_tree (), buf, sizeof (buf), 0);
+ int ret = native_encode_expr (expr, buf, sizeof (buf), 0);
rust_assert (ret > 0);
size_t *ptr = (size_t *) buf;
return std::to_string (*ptr);
}
- bool const_values_equal (Bexpression *a, Bexpression *b)
+ bool const_values_equal (tree a, tree b)
{
- return operand_equal_p (a->get_tree (), b->get_tree (),
- OEP_ONLY_CONST | OEP_PURE_SAME);
+ return operand_equal_p (a, b, OEP_ONLY_CONST | OEP_PURE_SAME);
// printf ("comparing!\n");
// debug_tree (a->get_tree ());
// debug_tree (b->get_tree ());
// printf ("ok = %s\n", ok ? "true" : "false");
}
- Btype *wchar_type ()
+ tree wchar_type ()
{
tree wchar = make_unsigned_type (32);
TYPE_STRING_FLAG (wchar) = 1;
- return this->make_type (wchar);
+ return wchar;
}
int get_pointer_size ();
- Btype *raw_str_type ();
-
- Btype *integer_type (bool, int);
-
- Btype *float_type (int);
-
- Btype *complex_type (int);
-
- Btype *pointer_type (Btype *);
-
- Btype *reference_type (Btype *);
-
- Btype *immutable_type (Btype *);
-
- Btype *specify_abi_attribute (Btype *, Rust::ABI);
-
- Btype *insert_type_attribute (Btype *, const std::string &);
-
- Btype *function_type (const Btyped_identifier &,
- const std::vector<Btyped_identifier> &,
- const std::vector<Btyped_identifier> &, Btype *,
- const Location);
+ tree raw_str_type ();
- Btype *function_type_varadic (const Btyped_identifier &,
- const std::vector<Btyped_identifier> &,
- const std::vector<Btyped_identifier> &, Btype *,
- const Location);
+ tree integer_type (bool, int);
- Btype *function_ptr_type (Btype *, const std::vector<Btype *> &, Location);
+ tree float_type (int);
- Btype *struct_type (const std::vector<Btyped_identifier> &);
+ tree complex_type (int);
- Btype *union_type (const std::vector<Btyped_identifier> &);
+ tree pointer_type (tree);
- Btype *array_type (Btype *, Bexpression *);
+ tree reference_type (tree);
- Btype *placeholder_pointer_type (const std::string &, Location, bool);
+ tree immutable_type (tree);
- bool set_placeholder_pointer_type (Btype *, Btype *);
+ tree specify_abi_attribute (tree, Rust::ABI);
- bool set_placeholder_function_type (Btype *, Btype *);
+ tree insert_type_attribute (tree, const std::string &);
- Btype *placeholder_struct_type (const std::string &, Location);
+ tree function_type (const typed_identifier &,
+ const std::vector<typed_identifier> &,
+ const std::vector<typed_identifier> &, tree,
+ const Location);
- bool set_placeholder_struct_type (Btype *placeholder,
- const std::vector<Btyped_identifier> &);
+ tree function_type_varadic (const typed_identifier &,
+ const std::vector<typed_identifier> &,
+ const std::vector<typed_identifier> &, tree,
+ const Location);
- Btype *placeholder_array_type (const std::string &, Location);
+ tree function_ptr_type (tree, const std::vector<tree> &, Location);
- bool set_placeholder_array_type (Btype *, Btype *, Bexpression *);
+ tree struct_type (const std::vector<typed_identifier> &);
- Btype *named_type (const std::string &, Btype *, Location);
+ tree union_type (const std::vector<typed_identifier> &);
- Btype *circular_pointer_type (Btype *, bool);
+ tree array_type (tree, tree);
- bool is_circular_pointer_type (Btype *);
+ tree named_type (const std::string &, tree, Location);
- int64_t type_size (Btype *);
+ int64_t type_size (tree);
- int64_t type_alignment (Btype *);
+ int64_t type_alignment (tree);
- int64_t type_field_alignment (Btype *);
+ int64_t type_field_alignment (tree);
- int64_t type_field_offset (Btype *, size_t index);
+ int64_t type_field_offset (tree, size_t index);
// Expressions.
- Bexpression *zero_expression (Btype *);
+ tree zero_expression (tree);
- Bexpression *error_expression ()
- {
- return this->make_expression (error_mark_node);
- }
+ tree error_expression () { return error_mark_node; }
- bool is_error_expression (Bexpression *expr)
- {
- return expr->get_tree () == error_mark_node;
- }
+ bool is_error_expression (tree expr) { return expr == error_mark_node; }
- Bexpression *nil_pointer_expression ()
- {
- return this->make_expression (null_pointer_node);
- }
+ tree nil_pointer_expression () { return null_pointer_node; }
- Bexpression *unit_expression ()
- {
- return this->make_expression (integer_zero_node);
- }
+ tree unit_expression () { return integer_zero_node; }
- Bexpression *var_expression (Bvariable *var, Location);
+ tree var_expression (Bvariable *var, Location);
- Bexpression *indirect_expression (Btype *, Bexpression *expr,
- bool known_valid, Location);
+ tree indirect_expression (tree, tree expr, bool known_valid, Location);
- Bexpression *named_constant_expression (Btype *btype, const std::string &name,
- Bexpression *val, Location);
+ tree named_constant_expression (tree type, const std::string &name, tree val,
+ Location);
- Bexpression *integer_constant_expression (Btype *btype, mpz_t val);
+ tree integer_constant_expression (tree type, mpz_t val);
- Bexpression *float_constant_expression (Btype *btype, mpfr_t val);
+ tree float_constant_expression (tree type, mpfr_t val);
- Bexpression *complex_constant_expression (Btype *btype, mpc_t val);
+ tree complex_constant_expression (tree type, mpc_t val);
- Bexpression *string_constant_expression (const std::string &val);
+ tree string_constant_expression (const std::string &val);
- Bexpression *wchar_constant_expression (wchar_t c);
+ tree wchar_constant_expression (wchar_t c);
- Bexpression *char_constant_expression (char c);
+ tree char_constant_expression (char c);
- Bexpression *boolean_constant_expression (bool val);
+ tree boolean_constant_expression (bool val);
- Bexpression *real_part_expression (Bexpression *bcomplex, Location);
+ tree real_part_expression (tree bcomplex, Location);
- Bexpression *imag_part_expression (Bexpression *bcomplex, Location);
+ tree imag_part_expression (tree bcomplex, Location);
- Bexpression *complex_expression (Bexpression *breal, Bexpression *bimag,
- Location);
+ tree complex_expression (tree breal, tree bimag, Location);
- Bexpression *convert_expression (Btype *type, Bexpression *expr, Location);
+ tree convert_expression (tree type, tree expr, Location);
- Bexpression *function_code_expression (Bfunction *, Location);
+ tree function_code_expression (tree, Location);
- Bexpression *address_expression (Bexpression *, Location);
+ tree address_expression (tree, Location);
- Bexpression *struct_field_expression (Bexpression *, size_t, Location);
+ tree struct_field_expression (tree, size_t, Location);
- Bexpression *compound_expression (Bstatement *, Bexpression *, Location);
+ tree compound_expression (tree, tree, Location);
- Bexpression *conditional_expression (Bfunction *, Btype *, Bexpression *,
- Bexpression *, Bexpression *, Location);
+ tree conditional_expression (tree, tree, tree, tree, tree, Location);
- Bexpression *negation_expression (NegationOperator op, Bexpression *expr,
- Location);
+ tree negation_expression (NegationOperator op, tree expr, Location);
- Bexpression *arithmetic_or_logical_expression (ArithmeticOrLogicalOperator op,
- Bexpression *left,
- Bexpression *right, Location);
+ tree arithmetic_or_logical_expression (ArithmeticOrLogicalOperator op,
+ tree left, tree right, Location);
- Bexpression *comparison_expression (ComparisonOperator op, Bexpression *left,
- Bexpression *right, Location);
+ tree comparison_expression (ComparisonOperator op, tree left, tree right,
+ Location);
- Bexpression *lazy_boolean_expression (LazyBooleanOperator op,
- Bexpression *left, Bexpression *right,
- Location);
+ tree lazy_boolean_expression (LazyBooleanOperator op, tree left, tree right,
+ Location);
- Bexpression *constructor_expression (Btype *,
- const std::vector<Bexpression *> &, int,
- Location);
+ tree constructor_expression (tree, const std::vector<tree> &, int, Location);
- Bexpression *array_constructor_expression (Btype *,
- const std::vector<unsigned long> &,
- const std::vector<Bexpression *> &,
- Location);
+ tree array_constructor_expression (tree, const std::vector<unsigned long> &,
+ const std::vector<tree> &, Location);
- Bexpression *pointer_offset_expression (Bexpression *base,
- Bexpression *offset, Location);
+ tree pointer_offset_expression (tree base, tree offset, Location);
- Bexpression *array_index_expression (Bexpression *array, Bexpression *index,
- Location);
+ tree array_index_expression (tree array, tree index, Location);
- Bexpression *call_expression (Bfunction *caller, Bexpression *fn,
- const std::vector<Bexpression *> &args,
- Bexpression *static_chain, Location);
+ tree call_expression (tree caller, tree fn, const std::vector<tree> &args,
+ tree static_chain, Location);
// Statements.
- Bstatement *error_statement ()
- {
- return this->make_statement (error_mark_node);
- }
+ tree error_statement () { return error_mark_node; }
- Bstatement *expression_statement (Bfunction *, Bexpression *);
+ tree expression_statement (tree, tree);
- Bstatement *init_statement (Bfunction *, Bvariable *var, Bexpression *init);
+ tree init_statement (tree, Bvariable *var, tree init);
- Bstatement *assignment_statement (Bfunction *, Bexpression *lhs,
- Bexpression *rhs, Location);
+ tree assignment_statement (tree, tree lhs, tree rhs, Location);
- Bstatement *return_statement (Bfunction *, const std::vector<Bexpression *> &,
- Location);
+ tree return_statement (tree, const std::vector<tree> &, Location);
- Bstatement *if_statement (Bfunction *, Bexpression *condition,
- Bblock *then_block, Bblock *else_block, Location);
+ tree if_statement (tree, tree condition, tree then_block, tree else_block,
+ Location);
- Bstatement *
- switch_statement (Bfunction *function, Bexpression *value,
- const std::vector<std::vector<Bexpression *> > &cases,
- const std::vector<Bstatement *> &statements, Location);
+ tree switch_statement (tree function, tree value,
+ const std::vector<std::vector<tree>> &cases,
+ const std::vector<tree> &statements, Location);
- Bstatement *compound_statement (Bstatement *, Bstatement *);
+ tree compound_statement (tree, tree);
- Bstatement *statement_list (const std::vector<Bstatement *> &);
+ tree statement_list (const std::vector<tree> &);
- Bstatement *exception_handler_statement (Bstatement *bstat,
- Bstatement *except_stmt,
- Bstatement *finally_stmt, Location);
+ tree exception_handler_statement (tree bstat, tree except_stmt,
+ tree finally_stmt, Location);
- Bexpression *loop_expression (Bblock *body, Location);
+ tree loop_expression (tree body, Location);
- Bexpression *exit_expression (Bexpression *condition, Location);
+ tree exit_expression (tree condition, Location);
// Blocks.
- Bblock *block (Bfunction *, Bblock *, const std::vector<Bvariable *> &,
- Location, Location);
+ tree block (tree, tree, const std::vector<Bvariable *> &, Location, Location);
- void block_add_statements (Bblock *, const std::vector<Bstatement *> &);
+ void block_add_statements (tree, const std::vector<tree> &);
- Bstatement *block_statement (Bblock *);
+ tree block_statement (tree);
// Variables.
Bvariable *error_variable () { return new Bvariable (error_mark_node); }
Bvariable *global_variable (const std::string &var_name,
- const std::string &asm_name, Btype *btype,
+ const std::string &asm_name, tree type,
bool is_external, bool is_hidden,
bool in_unique_section, Location location);
- void global_variable_set_init (Bvariable *, Bexpression *);
+ void global_variable_set_init (Bvariable *, tree);
- Bvariable *local_variable (Bfunction *, const std::string &, Btype *,
- Bvariable *, bool, Location);
+ Bvariable *local_variable (tree, const std::string &, tree, Bvariable *, bool,
+ Location);
- Bvariable *parameter_variable (Bfunction *, const std::string &, Btype *,
- bool, Location);
+ Bvariable *parameter_variable (tree, const std::string &, tree, bool,
+ Location);
- Bvariable *static_chain_variable (Bfunction *, const std::string &, Btype *,
- Location);
+ Bvariable *static_chain_variable (tree, const std::string &, tree, Location);
- Bvariable *temporary_variable (Bfunction *, Bblock *, Btype *, Bexpression *,
- bool, Location, Bstatement **);
+ Bvariable *temporary_variable (tree, tree, tree, tree, bool, Location,
+ tree *);
- Bvariable *implicit_variable (const std::string &, const std::string &,
- Btype *, bool, bool, bool, int64_t);
+ Bvariable *implicit_variable (const std::string &, const std::string &, tree,
+ bool, bool, bool, int64_t);
- void implicit_variable_set_init (Bvariable *, const std::string &, Btype *,
- bool, bool, bool, Bexpression *);
+ void implicit_variable_set_init (Bvariable *, const std::string &, tree, bool,
+ bool, bool, tree);
Bvariable *implicit_variable_reference (const std::string &,
- const std::string &, Btype *);
+ const std::string &, tree);
Bvariable *immutable_struct (const std::string &, const std::string &, bool,
- bool, Btype *, Location);
+ bool, tree, Location);
void immutable_struct_set_init (Bvariable *, const std::string &, bool, bool,
- Btype *, Location, Bexpression *);
+ tree, Location, tree);
Bvariable *immutable_struct_reference (const std::string &,
- const std::string &, Btype *,
- Location);
+ const std::string &, tree, Location);
// Labels.
- Blabel *label (Bfunction *, const std::string &name, Location);
+ tree label (tree, const std::string &name, Location);
- Bstatement *label_definition_statement (Blabel *);
+ tree label_definition_statement (tree);
- Bstatement *goto_statement (Blabel *, Location);
+ tree goto_statement (tree, Location);
- Bexpression *label_address (Blabel *, Location);
+ tree label_address (tree, Location);
// Functions.
- Bfunction *error_function () { return this->make_function (error_mark_node); }
+ tree error_function () { return error_mark_node; }
- Bfunction *function (Btype *fntype, const std::string &name,
- const std::string &asm_name, unsigned int flags,
- Location);
+ tree function (tree fntype, const std::string &name,
+ const std::string &asm_name, unsigned int flags, Location);
- Bstatement *function_defer_statement (Bfunction *function,
- Bexpression *undefer,
- Bexpression *defer, Location);
+ tree function_defer_statement (tree function, tree undefer, tree defer,
+ Location);
- bool function_set_parameters (Bfunction *function,
+ bool function_set_parameters (tree function,
const std::vector<Bvariable *> &);
- bool function_set_body (Bfunction *function, Bstatement *code_stmt);
+ bool function_set_body (tree function, tree code_stmt);
- Bfunction *lookup_gcc_builtin (const std::string &);
+ tree lookup_gcc_builtin (const std::string &);
- Bfunction *lookup_builtin_by_rust_name (const std::string &);
+ tree lookup_builtin_by_rust_name (const std::string &);
- void write_global_definitions (const std::vector<Btype *> &,
- const std::vector<Bexpression *> &,
- const std::vector<Bfunction *> &,
+ void write_global_definitions (const std::vector<tree> &,
+ const std::vector<tree> &,
+ const std::vector<tree> &,
const std::vector<Bvariable *> &);
void write_export_data (const char *bytes, unsigned int size);
private:
- // Make a Bexpression from a tree.
- Bexpression *make_expression (tree t) { return new Bexpression (t); }
-
- // Make a Bstatement from a tree.
- Bstatement *make_statement (tree t) { return new Bstatement (t); }
+ tree fill_in_fields (tree, const std::vector<typed_identifier> &);
- // Make a Btype from a tree.
- Btype *make_type (tree t) { return new Btype (t); }
-
- Bfunction *make_function (tree t) { return new Bfunction (t); }
-
- Btype *fill_in_fields (Btype *, const std::vector<Btyped_identifier> &);
-
- Btype *fill_in_array (Btype *, Btype *, Bexpression *);
+ tree fill_in_array (tree, tree, tree);
tree non_zero_size_type (tree);
@@ -558,7 +433,7 @@ private:
int flags);
// A mapping of the GCC built-ins exposed to GCCRust.
- std::map<std::string, Bfunction *> builtin_functions_;
+ std::map<std::string, tree> builtin_functions_;
std::map<std::string, std::string> rust_intrinsic_to_gcc_builtin;
};
@@ -810,15 +685,15 @@ Gcc_backend::get_pointer_size ()
return POINTER_SIZE;
}
-Btype *
+tree
Gcc_backend::raw_str_type ()
{
tree char_ptr = build_pointer_type (char_type_node);
tree const_char_type = build_qualified_type (char_ptr, TYPE_QUAL_CONST);
- return this->make_type (const_char_type);
+ return const_char_type;
}
-Btype *
+tree
Gcc_backend::integer_type (bool is_unsigned, int bits)
{
tree type;
@@ -848,12 +723,12 @@ Gcc_backend::integer_type (bool is_unsigned, int bits)
else
type = make_signed_type (bits);
}
- return this->make_type (type);
+ return type;
}
// Get an unnamed float type.
-Btype *
+tree
Gcc_backend::float_type (int bits)
{
tree type;
@@ -869,12 +744,12 @@ Gcc_backend::float_type (int bits)
TYPE_PRECISION (type) = bits;
layout_type (type);
}
- return this->make_type (type);
+ return type;
}
// Get an unnamed complex type.
-Btype *
+tree
Gcc_backend::complex_type (int bits)
{
tree type;
@@ -891,49 +766,46 @@ Gcc_backend::complex_type (int bits)
layout_type (type);
type = build_complex_type (type);
}
- return this->make_type (type);
+ return type;
}
// Get a pointer type.
-Btype *
-Gcc_backend::pointer_type (Btype *to_type)
+tree
+Gcc_backend::pointer_type (tree to_type)
{
- tree to_type_tree = to_type->get_tree ();
- if (to_type_tree == error_mark_node)
+ if (to_type == error_mark_node)
return this->error_type ();
- tree type = build_pointer_type (to_type_tree);
- return this->make_type (type);
+ tree type = build_pointer_type (to_type);
+ return type;
}
// Get a reference type.
-Btype *
-Gcc_backend::reference_type (Btype *to_type)
+tree
+Gcc_backend::reference_type (tree to_type)
{
- tree to_type_tree = to_type->get_tree ();
- if (to_type_tree == error_mark_node)
+ if (to_type == error_mark_node)
return this->error_type ();
- tree type = build_reference_type (to_type_tree);
- return this->make_type (type);
+ tree type = build_reference_type (to_type);
+ return type;
}
// Get immutable type
-Btype *
-Gcc_backend::immutable_type (Btype *base)
+tree
+Gcc_backend::immutable_type (tree base)
{
- tree type_tree = base->get_tree ();
- if (type_tree == error_mark_node)
+ if (base == error_mark_node)
return this->error_type ();
- tree constified = build_qualified_type (type_tree, TYPE_QUAL_CONST);
- return this->make_type (constified);
+ tree constified = build_qualified_type (base, TYPE_QUAL_CONST);
+ return constified;
}
// ABI
-Btype *
-Gcc_backend::specify_abi_attribute (Btype *type, Rust::ABI abi)
+tree
+Gcc_backend::specify_abi_attribute (tree type, Rust::ABI abi)
{
std::string abi_string;
switch (abi)
@@ -959,46 +831,46 @@ Gcc_backend::specify_abi_attribute (Btype *type, Rust::ABI abi)
return insert_type_attribute (type, abi_string);
}
-Btype *
-Gcc_backend::insert_type_attribute (Btype *type, const std::string &attrname)
+tree
+Gcc_backend::insert_type_attribute (tree type, const std::string &attrname)
{
tree ident = get_identifier (attrname.c_str ());
tree attribs = NULL_TREE;
- tree old_attrs = TYPE_ATTRIBUTES (type->get_tree ());
+ tree old_attrs = TYPE_ATTRIBUTES (type);
if (old_attrs)
attribs = merge_type_attributes (old_attrs,
tree_cons (ident, NULL_TREE, NULL_TREE));
else
attribs = tree_cons (ident, NULL_TREE, NULL_TREE);
- tree res = build_type_attribute_variant (type->get_tree (), attribs);
- return this->make_type (res);
+ tree res = build_type_attribute_variant (type, attribs);
+ return res;
}
// Make a function type.
-Btype *
-Gcc_backend::function_type (const Btyped_identifier &receiver,
- const std::vector<Btyped_identifier> &parameters,
- const std::vector<Btyped_identifier> &results,
- Btype *result_struct, Location)
+tree
+Gcc_backend::function_type (const typed_identifier &receiver,
+ const std::vector<typed_identifier> &parameters,
+ const std::vector<typed_identifier> &results,
+ tree result_struct, Location)
{
tree args = NULL_TREE;
tree *pp = &args;
- if (receiver.btype != NULL)
+ if (receiver.type != NULL_TREE)
{
- tree t = receiver.btype->get_tree ();
+ tree t = receiver.type;
if (t == error_mark_node)
return this->error_type ();
*pp = tree_cons (NULL_TREE, t, NULL_TREE);
pp = &TREE_CHAIN (*pp);
}
- for (std::vector<Btyped_identifier>::const_iterator p = parameters.begin ();
+ for (std::vector<typed_identifier>::const_iterator p = parameters.begin ();
p != parameters.end (); ++p)
{
- tree t = p->btype->get_tree ();
+ tree t = p->type;
if (t == error_mark_node)
return this->error_type ();
*pp = tree_cons (NULL_TREE, t, NULL_TREE);
@@ -1013,11 +885,11 @@ Gcc_backend::function_type (const Btyped_identifier &receiver,
if (results.empty ())
result = void_type_node;
else if (results.size () == 1)
- result = results.front ().btype->get_tree ();
+ result = results.front ().type;
else
{
gcc_assert (result_struct != NULL);
- result = result_struct->get_tree ();
+ result = result_struct;
}
if (result == error_mark_node)
return this->error_type ();
@@ -1034,32 +906,32 @@ Gcc_backend::function_type (const Btyped_identifier &receiver,
if (fntype == error_mark_node)
return this->error_type ();
- return this->make_type (build_pointer_type (fntype));
+ return build_pointer_type (fntype);
}
-Btype *
+tree
Gcc_backend::function_type_varadic (
- const Btyped_identifier &receiver,
- const std::vector<Btyped_identifier> &parameters,
- const std::vector<Btyped_identifier> &results, Btype *result_struct, Location)
+ const typed_identifier &receiver,
+ const std::vector<typed_identifier> &parameters,
+ const std::vector<typed_identifier> &results, tree result_struct, Location)
{
- size_t n = parameters.size () + (receiver.btype != NULL ? 1 : 0);
+ size_t n = parameters.size () + (receiver.type != NULL_TREE ? 1 : 0);
tree *args = XALLOCAVEC (tree, n);
size_t offs = 0;
- if (receiver.btype != NULL)
+ if (receiver.type != NULL_TREE)
{
- tree t = receiver.btype->get_tree ();
+ tree t = receiver.type;
if (t == error_mark_node)
return this->error_type ();
args[offs++] = t;
}
- for (std::vector<Btyped_identifier>::const_iterator p = parameters.begin ();
+ for (std::vector<typed_identifier>::const_iterator p = parameters.begin ();
p != parameters.end (); ++p)
{
- tree t = p->btype->get_tree ();
+ tree t = p->type;
if (t == error_mark_node)
return this->error_type ();
args[offs++] = t;
@@ -1069,11 +941,11 @@ Gcc_backend::function_type_varadic (
if (results.empty ())
result = void_type_node;
else if (results.size () == 1)
- result = results.front ().btype->get_tree ();
+ result = results.front ().type;
else
{
- gcc_assert (result_struct != NULL);
- result = result_struct->get_tree ();
+ gcc_assert (result_struct != NULL_TREE);
+ result = result_struct;
}
if (result == error_mark_node)
return this->error_type ();
@@ -1090,12 +962,12 @@ Gcc_backend::function_type_varadic (
if (fntype == error_mark_node)
return this->error_type ();
- return this->make_type (build_pointer_type (fntype));
+ return build_pointer_type (fntype);
}
-Btype *
-Gcc_backend::function_ptr_type (Btype *result_type,
- const std::vector<Btype *> &parameters,
+tree
+Gcc_backend::function_ptr_type (tree result_type,
+ const std::vector<tree> &parameters,
Location /* locus */)
{
tree args = NULL_TREE;
@@ -1103,17 +975,16 @@ Gcc_backend::function_ptr_type (Btype *result_type,
for (auto &param : parameters)
{
- tree t = param->get_tree ();
- if (t == error_mark_node)
+ if (param == error_mark_node)
return this->error_type ();
- *pp = tree_cons (NULL_TREE, t, NULL_TREE);
+ *pp = tree_cons (NULL_TREE, param, NULL_TREE);
pp = &TREE_CHAIN (*pp);
}
*pp = void_list_node;
- tree result = result_type->get_tree ();
+ tree result = result_type;
if (result != void_type_node && int_size_in_bytes (result) == 0)
result = void_type_node;
@@ -1121,82 +992,75 @@ Gcc_backend::function_ptr_type (Btype *result_type,
if (fntype == error_mark_node)
return this->error_type ();
- return this->make_type (build_pointer_type (fntype));
+ return build_pointer_type (fntype);
}
// Make a struct type.
-Btype *
-Gcc_backend::struct_type (const std::vector<Btyped_identifier> &fields)
+tree
+Gcc_backend::struct_type (const std::vector<typed_identifier> &fields)
{
- return this->fill_in_fields (this->make_type (make_node (RECORD_TYPE)),
- fields);
+ return this->fill_in_fields (make_node (RECORD_TYPE), fields);
}
// Make a union type.
-Btype *
-Gcc_backend::union_type (const std::vector<Btyped_identifier> &fields)
+tree
+Gcc_backend::union_type (const std::vector<typed_identifier> &fields)
{
- return this->fill_in_fields (this->make_type (make_node (UNION_TYPE)),
- fields);
+ return this->fill_in_fields (make_node (UNION_TYPE), fields);
}
// Fill in the fields of a struct or union type.
-Btype *
-Gcc_backend::fill_in_fields (Btype *fill,
- const std::vector<Btyped_identifier> &fields)
+tree
+Gcc_backend::fill_in_fields (tree fill,
+ const std::vector<typed_identifier> &fields)
{
- tree fill_tree = fill->get_tree ();
tree field_trees = NULL_TREE;
tree *pp = &field_trees;
- for (std::vector<Btyped_identifier>::const_iterator p = fields.begin ();
+ for (std::vector<typed_identifier>::const_iterator p = fields.begin ();
p != fields.end (); ++p)
{
tree name_tree = get_identifier_from_string (p->name);
- tree type_tree = p->btype->get_tree ();
+ tree type_tree = p->type;
if (type_tree == error_mark_node)
return this->error_type ();
tree field = build_decl (p->location.gcc_location (), FIELD_DECL,
name_tree, type_tree);
- DECL_CONTEXT (field) = fill_tree;
+ DECL_CONTEXT (field) = fill;
*pp = field;
pp = &DECL_CHAIN (field);
}
- TYPE_FIELDS (fill_tree) = field_trees;
- layout_type (fill_tree);
+ TYPE_FIELDS (fill) = field_trees;
+ layout_type (fill);
// Because Rust permits converting between named struct types and
// equivalent struct types, for which we use VIEW_CONVERT_EXPR, and
// because we don't try to maintain TYPE_CANONICAL for struct types,
// we need to tell the middle-end to use structural equality.
- SET_TYPE_STRUCTURAL_EQUALITY (fill_tree);
+ SET_TYPE_STRUCTURAL_EQUALITY (fill);
return fill;
}
// Make an array type.
-Btype *
-Gcc_backend::array_type (Btype *element_btype, Bexpression *length)
+tree
+Gcc_backend::array_type (tree element_type, tree length)
{
- return this->fill_in_array (this->make_type (make_node (ARRAY_TYPE)),
- element_btype, length);
+ return this->fill_in_array (make_node (ARRAY_TYPE), element_type, length);
}
// Fill in an array type.
-Btype *
-Gcc_backend::fill_in_array (Btype *fill, Btype *element_type,
- Bexpression *length)
+tree
+Gcc_backend::fill_in_array (tree fill, tree element_type, tree length_tree)
{
- tree element_type_tree = element_type->get_tree ();
- tree length_tree = length->get_tree ();
- if (element_type_tree == error_mark_node || length_tree == error_mark_node)
+ if (element_type == error_mark_node || length_tree == error_mark_node)
return this->error_type ();
- gcc_assert (TYPE_SIZE (element_type_tree) != NULL_TREE);
+ gcc_assert (TYPE_SIZE (element_type) != NULL_TREE);
length_tree = fold_convert (sizetype, length_tree);
@@ -1205,160 +1069,26 @@ Gcc_backend::fill_in_array (Btype *fill, Btype *element_type,
tree index_type_tree = build_index_type (
fold_build2 (MINUS_EXPR, sizetype, length_tree, size_one_node));
- tree fill_tree = fill->get_tree ();
- TREE_TYPE (fill_tree) = element_type_tree;
- TYPE_DOMAIN (fill_tree) = index_type_tree;
- TYPE_ADDR_SPACE (fill_tree) = TYPE_ADDR_SPACE (element_type_tree);
- layout_type (fill_tree);
+ TREE_TYPE (fill) = element_type;
+ TYPE_DOMAIN (fill) = index_type_tree;
+ TYPE_ADDR_SPACE (fill) = TYPE_ADDR_SPACE (element_type);
+ layout_type (fill);
- if (TYPE_STRUCTURAL_EQUALITY_P (element_type_tree))
- SET_TYPE_STRUCTURAL_EQUALITY (fill_tree);
- else if (TYPE_CANONICAL (element_type_tree) != element_type_tree
+ if (TYPE_STRUCTURAL_EQUALITY_P (element_type))
+ SET_TYPE_STRUCTURAL_EQUALITY (fill);
+ else if (TYPE_CANONICAL (element_type) != element_type
|| TYPE_CANONICAL (index_type_tree) != index_type_tree)
- TYPE_CANONICAL (fill_tree)
- = build_array_type (TYPE_CANONICAL (element_type_tree),
- TYPE_CANONICAL (index_type_tree));
+ TYPE_CANONICAL (fill) = build_array_type (TYPE_CANONICAL (element_type),
+ TYPE_CANONICAL (index_type_tree));
return fill;
}
-// Create a placeholder for a pointer type.
-
-Btype *
-Gcc_backend::placeholder_pointer_type (const std::string &name,
- Location location, bool)
-{
- tree ret = build_distinct_type_copy (ptr_type_node);
- if (!name.empty ())
- {
- tree decl = build_decl (location.gcc_location (), TYPE_DECL,
- get_identifier_from_string (name), ret);
- TYPE_NAME (ret) = decl;
- }
- return this->make_type (ret);
-}
-
-// Set the real target type for a placeholder pointer type.
-
-bool
-Gcc_backend::set_placeholder_pointer_type (Btype *placeholder, Btype *to_type)
-{
- tree pt = placeholder->get_tree ();
- if (pt == error_mark_node)
- return false;
- gcc_assert (TREE_CODE (pt) == POINTER_TYPE);
- tree tt = to_type->get_tree ();
- if (tt == error_mark_node)
- {
- placeholder->set_tree (error_mark_node);
- return false;
- }
- gcc_assert (TREE_CODE (tt) == POINTER_TYPE);
- TREE_TYPE (pt) = TREE_TYPE (tt);
- TYPE_CANONICAL (pt) = TYPE_CANONICAL (tt);
- if (TYPE_NAME (pt) != NULL_TREE)
- {
- // Build the data structure gcc wants to see for a typedef.
- tree copy = build_variant_type_copy (pt);
- TYPE_NAME (copy) = NULL_TREE;
- DECL_ORIGINAL_TYPE (TYPE_NAME (pt)) = copy;
- }
- return true;
-}
-
-// Set the real values for a placeholder function type.
-
-bool
-Gcc_backend::set_placeholder_function_type (Btype *placeholder, Btype *ft)
-{
- return this->set_placeholder_pointer_type (placeholder, ft);
-}
-
-// Create a placeholder for a struct type.
-
-Btype *
-Gcc_backend::placeholder_struct_type (const std::string &name,
- Location location)
-{
- tree ret = make_node (RECORD_TYPE);
- if (!name.empty ())
- {
- tree decl = build_decl (location.gcc_location (), TYPE_DECL,
- get_identifier_from_string (name), ret);
- TYPE_NAME (ret) = decl;
-
- // The struct type that eventually replaces this placeholder will require
- // structural equality. The placeholder must too, so that the requirement
- // for structural equality propagates to references that are constructed
- // before the replacement occurs.
- SET_TYPE_STRUCTURAL_EQUALITY (ret);
- }
- return this->make_type (ret);
-}
-
-// Fill in the fields of a placeholder struct type.
-
-bool
-Gcc_backend::set_placeholder_struct_type (
- Btype *placeholder, const std::vector<Btyped_identifier> &fields)
-{
- tree t = placeholder->get_tree ();
- gcc_assert (TREE_CODE (t) == RECORD_TYPE && TYPE_FIELDS (t) == NULL_TREE);
- Btype *r = this->fill_in_fields (placeholder, fields);
-
- if (TYPE_NAME (t) != NULL_TREE)
- {
- // Build the data structure gcc wants to see for a typedef.
- tree copy = build_distinct_type_copy (t);
- TYPE_NAME (copy) = NULL_TREE;
- DECL_ORIGINAL_TYPE (TYPE_NAME (t)) = copy;
- TYPE_SIZE (copy) = NULL_TREE;
- Btype *bc = this->make_type (copy);
- this->fill_in_fields (bc, fields);
- delete bc;
- }
-
- return r->get_tree () != error_mark_node;
-}
-
-// Create a placeholder for an array type.
-
-Btype *
-Gcc_backend::placeholder_array_type (const std::string &name, Location location)
-{
- tree ret = make_node (ARRAY_TYPE);
- tree decl = build_decl (location.gcc_location (), TYPE_DECL,
- get_identifier_from_string (name), ret);
- TYPE_NAME (ret) = decl;
- return this->make_type (ret);
-}
-
-// Fill in the fields of a placeholder array type.
-
-bool
-Gcc_backend::set_placeholder_array_type (Btype *placeholder,
- Btype *element_btype,
- Bexpression *length)
-{
- tree t = placeholder->get_tree ();
- gcc_assert (TREE_CODE (t) == ARRAY_TYPE && TREE_TYPE (t) == NULL_TREE);
- Btype *r = this->fill_in_array (placeholder, element_btype, length);
-
- // Build the data structure gcc wants to see for a typedef.
- tree copy = build_distinct_type_copy (t);
- TYPE_NAME (copy) = NULL_TREE;
- DECL_ORIGINAL_TYPE (TYPE_NAME (t)) = copy;
-
- return r->get_tree () != error_mark_node;
-}
-
// Return a named version of a type.
-Btype *
-Gcc_backend::named_type (const std::string &name, Btype *btype,
- Location location)
+tree
+Gcc_backend::named_type (const std::string &name, tree type, Location location)
{
- tree type = btype->get_tree ();
if (type == error_mark_node)
return this->error_type ();
@@ -1374,7 +1104,7 @@ Gcc_backend::named_type (const std::string &name, Btype *btype,
tree decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
get_identifier_from_string (name), type);
TYPE_NAME (type) = decl;
- return this->make_type (type);
+ return type;
}
tree copy = build_variant_type_copy (type);
@@ -1382,31 +1112,14 @@ Gcc_backend::named_type (const std::string &name, Btype *btype,
get_identifier_from_string (name), copy);
DECL_ORIGINAL_TYPE (decl) = type;
TYPE_NAME (copy) = decl;
- return this->make_type (copy);
-}
-
-// Return a pointer type used as a marker for a circular type.
-
-Btype *
-Gcc_backend::circular_pointer_type (Btype *, bool)
-{
- return this->make_type (ptr_type_node);
-}
-
-// Return whether we might be looking at a circular type.
-
-bool
-Gcc_backend::is_circular_pointer_type (Btype *btype)
-{
- return btype->get_tree () == ptr_type_node;
+ return copy;
}
// Return the size of a type.
int64_t
-Gcc_backend::type_size (Btype *btype)
+Gcc_backend::type_size (tree t)
{
- tree t = btype->get_tree ();
if (t == error_mark_node)
return 1;
if (t == void_type_node)
@@ -1423,9 +1136,8 @@ Gcc_backend::type_size (Btype *btype)
// Return the alignment of a type.
int64_t
-Gcc_backend::type_alignment (Btype *btype)
+Gcc_backend::type_alignment (tree t)
{
- tree t = btype->get_tree ();
if (t == error_mark_node)
return 1;
return TYPE_ALIGN_UNIT (t);
@@ -1434,9 +1146,8 @@ Gcc_backend::type_alignment (Btype *btype)
// Return the alignment of a struct field of type BTYPE.
int64_t
-Gcc_backend::type_field_alignment (Btype *btype)
+Gcc_backend::type_field_alignment (tree t)
{
- tree t = btype->get_tree ();
if (t == error_mark_node)
return 1;
return rust_field_alignment (t);
@@ -1445,9 +1156,8 @@ Gcc_backend::type_field_alignment (Btype *btype)
// Return the offset of a field in a struct.
int64_t
-Gcc_backend::type_field_offset (Btype *btype, size_t index)
+Gcc_backend::type_field_offset (tree struct_tree, size_t index)
{
- tree struct_tree = btype->get_tree ();
if (struct_tree == error_mark_node)
return 0;
gcc_assert (TREE_CODE (struct_tree) == RECORD_TYPE);
@@ -1465,37 +1175,34 @@ Gcc_backend::type_field_offset (Btype *btype, size_t index)
// Return the zero value for a type.
-Bexpression *
-Gcc_backend::zero_expression (Btype *btype)
+tree
+Gcc_backend::zero_expression (tree t)
{
- tree t = btype->get_tree ();
tree ret;
if (t == error_mark_node)
ret = error_mark_node;
else
ret = build_zero_cst (t);
- return this->make_expression (ret);
+ return ret;
}
// An expression that references a variable.
-Bexpression *
+tree
Gcc_backend::var_expression (Bvariable *var, Location location)
{
tree ret = var->get_tree (location);
if (ret == error_mark_node)
return this->error_expression ();
- return this->make_expression (ret);
+ return ret;
}
// An expression that indirectly references an expression.
-Bexpression *
-Gcc_backend::indirect_expression (Btype *btype, Bexpression *expr,
+tree
+Gcc_backend::indirect_expression (tree type_tree, tree expr_tree,
bool known_valid, Location location)
{
- tree expr_tree = expr->get_tree ();
- tree type_tree = btype->get_tree ();
if (expr_tree == error_mark_node || type_tree == error_mark_node)
return this->error_expression ();
@@ -1509,18 +1216,16 @@ Gcc_backend::indirect_expression (Btype *btype, Bexpression *expr,
tree ret = build_fold_indirect_ref_loc (location.gcc_location (), expr_tree);
if (known_valid)
TREE_THIS_NOTRAP (ret) = 1;
- return this->make_expression (ret);
+ return ret;
}
// Return an expression that declares a constant named NAME with the
// constant value VAL in BTYPE.
-Bexpression *
-Gcc_backend::named_constant_expression (Btype *btype, const std::string &name,
- Bexpression *val, Location location)
+tree
+Gcc_backend::named_constant_expression (tree type_tree, const std::string &name,
+ tree const_val, Location location)
{
- tree type_tree = btype->get_tree ();
- tree const_val = val->get_tree ();
if (type_tree == error_mark_node || const_val == error_mark_node)
return this->error_expression ();
@@ -1532,28 +1237,26 @@ Gcc_backend::named_constant_expression (Btype *btype, const std::string &name,
TREE_READONLY (decl) = 1;
rust_preserve_from_gc (decl);
- return this->make_expression (decl);
+ return decl;
}
// Return a typed value as a constant integer.
-Bexpression *
-Gcc_backend::integer_constant_expression (Btype *btype, mpz_t val)
+tree
+Gcc_backend::integer_constant_expression (tree t, mpz_t val)
{
- tree t = btype->get_tree ();
if (t == error_mark_node)
return this->error_expression ();
tree ret = double_int_to_tree (t, mpz_get_double_int (t, val, true));
- return this->make_expression (ret);
+ return ret;
}
// Return a typed value as a constant floating-point number.
-Bexpression *
-Gcc_backend::float_constant_expression (Btype *btype, mpfr_t val)
+tree
+Gcc_backend::float_constant_expression (tree t, mpfr_t val)
{
- tree t = btype->get_tree ();
tree ret;
if (t == error_mark_node)
return this->error_expression ();
@@ -1563,15 +1266,14 @@ Gcc_backend::float_constant_expression (Btype *btype, mpfr_t val)
REAL_VALUE_TYPE r2;
real_convert (&r2, TYPE_MODE (t), &r1);
ret = build_real (t, r2);
- return this->make_expression (ret);
+ return ret;
}
// Return a typed real and imaginary value as a constant complex number.
-Bexpression *
-Gcc_backend::complex_constant_expression (Btype *btype, mpc_t val)
+tree
+Gcc_backend::complex_constant_expression (tree t, mpc_t val)
{
- tree t = btype->get_tree ();
tree ret;
if (t == error_mark_node)
return this->error_expression ();
@@ -1588,12 +1290,12 @@ Gcc_backend::complex_constant_expression (Btype *btype, mpc_t val)
ret = build_complex (t, build_real (TREE_TYPE (t), r2),
build_real (TREE_TYPE (t), r4));
- return this->make_expression (ret);
+ return ret;
}
// Make a constant string expression.
-Bexpression *
+tree
Gcc_backend::string_constant_expression (const std::string &val)
{
tree index_type = build_index_type (size_int (val.length ()));
@@ -1603,70 +1305,63 @@ Gcc_backend::string_constant_expression (const std::string &val)
tree string_val = build_string (val.length (), val.data ());
TREE_TYPE (string_val) = string_type;
- return this->make_expression (string_val);
+ return string_val;
}
-Bexpression *
+tree
Gcc_backend::wchar_constant_expression (wchar_t c)
{
- tree ret = build_int_cst (this->wchar_type ()->get_tree (), c);
- return this->make_expression (ret);
+ return build_int_cst (this->wchar_type (), c);
}
-Bexpression *
+tree
Gcc_backend::char_constant_expression (char c)
{
- tree ret = build_int_cst (this->char_type ()->get_tree (), c);
- return this->make_expression (ret);
+ return build_int_cst (this->char_type (), c);
}
// Make a constant boolean expression.
-Bexpression *
+tree
Gcc_backend::boolean_constant_expression (bool val)
{
- tree bool_cst = val ? boolean_true_node : boolean_false_node;
- return this->make_expression (bool_cst);
+ return val ? boolean_true_node : boolean_false_node;
}
// Return the real part of a complex expression.
-Bexpression *
-Gcc_backend::real_part_expression (Bexpression *bcomplex, Location location)
+tree
+Gcc_backend::real_part_expression (tree complex_tree, Location location)
{
- tree complex_tree = bcomplex->get_tree ();
if (complex_tree == error_mark_node)
return this->error_expression ();
gcc_assert (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (complex_tree)));
tree ret
= fold_build1_loc (location.gcc_location (), REALPART_EXPR,
TREE_TYPE (TREE_TYPE (complex_tree)), complex_tree);
- return this->make_expression (ret);
+ return ret;
}
// Return the imaginary part of a complex expression.
-Bexpression *
-Gcc_backend::imag_part_expression (Bexpression *bcomplex, Location location)
+tree
+Gcc_backend::imag_part_expression (tree complex_tree, Location location)
{
- tree complex_tree = bcomplex->get_tree ();
if (complex_tree == error_mark_node)
return this->error_expression ();
gcc_assert (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (complex_tree)));
tree ret
= fold_build1_loc (location.gcc_location (), IMAGPART_EXPR,
TREE_TYPE (TREE_TYPE (complex_tree)), complex_tree);
- return this->make_expression (ret);
+ return ret;
}
// Make a complex expression given its real and imaginary parts.
-Bexpression *
-Gcc_backend::complex_expression (Bexpression *breal, Bexpression *bimag,
+tree
+Gcc_backend::complex_expression (tree real_tree, tree imag_tree,
Location location)
{
- tree real_tree = breal->get_tree ();
- tree imag_tree = bimag->get_tree ();
if (real_tree == error_mark_node || imag_tree == error_mark_node)
return this->error_expression ();
gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (real_tree))
@@ -1675,23 +1370,22 @@ Gcc_backend::complex_expression (Bexpression *breal, Bexpression *bimag,
tree ret = fold_build2_loc (location.gcc_location (), COMPLEX_EXPR,
build_complex_type (TREE_TYPE (real_tree)),
real_tree, imag_tree);
- return this->make_expression (ret);
+ return ret;
}
// An expression that converts an expression to a different type.
-Bexpression *
-Gcc_backend::convert_expression (Btype *type, Bexpression *expr,
+tree
+Gcc_backend::convert_expression (tree type_tree, tree expr_tree,
Location location)
{
- tree type_tree = type->get_tree ();
- tree expr_tree = expr->get_tree ();
if (type_tree == error_mark_node || expr_tree == error_mark_node
|| TREE_TYPE (expr_tree) == error_mark_node)
return this->error_expression ();
tree ret;
- if (this->type_size (type) == 0 || TREE_TYPE (expr_tree) == void_type_node)
+ if (this->type_size (type_tree) == 0
+ || TREE_TYPE (expr_tree) == void_type_node)
{
// Do not convert zero-sized types.
ret = expr_tree;
@@ -1712,42 +1406,38 @@ Gcc_backend::convert_expression (Btype *type, Bexpression *expr,
else
ret = fold_convert_loc (location.gcc_location (), type_tree, expr_tree);
- return this->make_expression (ret);
+ return ret;
}
// Get the address of a function.
-Bexpression *
-Gcc_backend::function_code_expression (Bfunction *bfunc, Location location)
+tree
+Gcc_backend::function_code_expression (tree func, Location location)
{
- tree func = bfunc->get_tree ();
if (func == error_mark_node)
return this->error_expression ();
tree ret = build_fold_addr_expr_loc (location.gcc_location (), func);
- return this->make_expression (ret);
+ return ret;
}
// Get the address of an expression.
-Bexpression *
-Gcc_backend::address_expression (Bexpression *bexpr, Location location)
+tree
+Gcc_backend::address_expression (tree expr, Location location)
{
- tree expr = bexpr->get_tree ();
if (expr == error_mark_node)
return this->error_expression ();
- tree ret = build_fold_addr_expr_loc (location.gcc_location (), expr);
- return this->make_expression (ret);
+ return build_fold_addr_expr_loc (location.gcc_location (), expr);
}
// Return an expression for the field at INDEX in BSTRUCT.
-Bexpression *
-Gcc_backend::struct_field_expression (Bexpression *bstruct, size_t index,
+tree
+Gcc_backend::struct_field_expression (tree struct_tree, size_t index,
Location location)
{
- tree struct_tree = bstruct->get_tree ();
if (struct_tree == error_mark_node
|| TREE_TYPE (struct_tree) == error_mark_node)
return this->error_expression ();
@@ -1771,43 +1461,35 @@ Gcc_backend::struct_field_expression (Bexpression *bstruct, size_t index,
TREE_TYPE (field), struct_tree, field, NULL_TREE);
if (TREE_CONSTANT (struct_tree))
TREE_CONSTANT (ret) = 1;
- return this->make_expression (ret);
+ return ret;
}
// Return an expression that executes BSTAT before BEXPR.
-Bexpression *
-Gcc_backend::compound_expression (Bstatement *bstat, Bexpression *bexpr,
- Location location)
+tree
+Gcc_backend::compound_expression (tree stat, tree expr, Location location)
{
- tree stat = bstat->get_tree ();
- tree expr = bexpr->get_tree ();
if (stat == error_mark_node || expr == error_mark_node)
return this->error_expression ();
tree ret = fold_build2_loc (location.gcc_location (), COMPOUND_EXPR,
TREE_TYPE (expr), stat, expr);
- return this->make_expression (ret);
+ return ret;
}
// Return an expression that executes THEN_EXPR if CONDITION is true, or
// ELSE_EXPR otherwise.
-Bexpression *
-Gcc_backend::conditional_expression (Bfunction *, Btype *btype,
- Bexpression *condition,
- Bexpression *then_expr,
- Bexpression *else_expr, Location location)
-{
- tree type_tree = btype == NULL ? void_type_node : btype->get_tree ();
- tree cond_tree = condition->get_tree ();
- tree then_tree = then_expr->get_tree ();
- tree else_tree = else_expr == NULL ? NULL_TREE : else_expr->get_tree ();
- if (type_tree == error_mark_node || cond_tree == error_mark_node
- || then_tree == error_mark_node || else_tree == error_mark_node)
+tree
+Gcc_backend::conditional_expression (tree, tree type_tree, tree cond_expr,
+ tree then_expr, tree else_expr,
+ Location location)
+{
+ if (type_tree == error_mark_node || cond_expr == error_mark_node
+ || then_expr == error_mark_node || else_expr == error_mark_node)
return this->error_expression ();
tree ret = build3_loc (location.gcc_location (), COND_EXPR, type_tree,
- cond_tree, then_tree, else_tree);
- return this->make_expression (ret);
+ cond_expr, then_expr, else_expr);
+ return ret;
}
/* Helper function that converts rust operators to equivalent GCC tree_code.
@@ -1909,13 +1591,12 @@ is_floating_point (tree t)
}
// Return an expression for the negation operation OP EXPR.
-Bexpression *
-Gcc_backend::negation_expression (NegationOperator op, Bexpression *expr,
+tree
+Gcc_backend::negation_expression (NegationOperator op, tree expr_tree,
Location location)
{
/* Check if the expression is an error, in which case we return an error
expression. */
- auto expr_tree = expr->get_tree ();
if (expr_tree == error_mark_node || TREE_TYPE (expr_tree) == error_mark_node)
return this->error_expression ();
@@ -1944,20 +1625,17 @@ Gcc_backend::negation_expression (NegationOperator op, Bexpression *expr,
tree_type, expr_tree);
if (floating_point && extended_type != NULL_TREE)
new_tree = convert (original_type, expr_tree);
- return this->make_expression (new_tree);
+ return new_tree;
}
// Return an expression for the arithmetic or logical operation LEFT OP RIGHT.
-Bexpression *
+tree
Gcc_backend::arithmetic_or_logical_expression (ArithmeticOrLogicalOperator op,
- Bexpression *left,
- Bexpression *right,
+ tree left_tree, tree right_tree,
Location location)
{
/* Check if either expression is an error, in which case we return an error
expression. */
- auto left_tree = left->get_tree ();
- auto right_tree = right->get_tree ();
if (left_tree == error_mark_node || right_tree == error_mark_node)
return this->error_expression ();
@@ -1990,18 +1668,16 @@ Gcc_backend::arithmetic_or_logical_expression (ArithmeticOrLogicalOperator op,
tree_type, left_tree, right_tree);
if (floating_point && extended_type != NULL_TREE)
new_tree = convert (original_type, new_tree);
- return this->make_expression (new_tree);
+ return new_tree;
}
// Return an expression for the comparison operation LEFT OP RIGHT.
-Bexpression *
-Gcc_backend::comparison_expression (ComparisonOperator op, Bexpression *left,
- Bexpression *right, Location location)
+tree
+Gcc_backend::comparison_expression (ComparisonOperator op, tree left_tree,
+ tree right_tree, Location location)
{
/* Check if either expression is an error, in which case we return an error
expression. */
- auto left_tree = left->get_tree ();
- auto right_tree = right->get_tree ();
if (left_tree == error_mark_node || right_tree == error_mark_node)
return this->error_expression ();
@@ -2012,18 +1688,16 @@ Gcc_backend::comparison_expression (ComparisonOperator op, Bexpression *left,
/* Construct a new tree and build an expression from it. */
auto new_tree = fold_build2_loc (location.gcc_location (), tree_code,
tree_type, left_tree, right_tree);
- return this->make_expression (new_tree);
+ return new_tree;
}
// Return an expression for the lazy boolean operation LEFT OP RIGHT.
-Bexpression *
-Gcc_backend::lazy_boolean_expression (LazyBooleanOperator op, Bexpression *left,
- Bexpression *right, Location location)
+tree
+Gcc_backend::lazy_boolean_expression (LazyBooleanOperator op, tree left_tree,
+ tree right_tree, Location location)
{
/* Check if either expression is an error, in which case we return an error
expression. */
- auto left_tree = left->get_tree ();
- auto right_tree = right->get_tree ();
if (left_tree == error_mark_node || right_tree == error_mark_node)
return this->error_expression ();
@@ -2035,17 +1709,16 @@ Gcc_backend::lazy_boolean_expression (LazyBooleanOperator op, Bexpression *left,
/* Construct a new tree and build an expression from it. */
auto new_tree = fold_build2_loc (location.gcc_location (), tree_code,
tree_type, left_tree, right_tree);
- return this->make_expression (new_tree);
+ return new_tree;
}
// Return an expression that constructs BTYPE with VALS.
-Bexpression *
-Gcc_backend::constructor_expression (Btype *btype,
- const std::vector<Bexpression *> &vals,
+tree
+Gcc_backend::constructor_expression (tree type_tree,
+ const std::vector<tree> &vals,
int union_index, Location location)
{
- tree type_tree = btype->get_tree ();
if (type_tree == error_mark_node)
return this->error_expression ();
@@ -2058,7 +1731,7 @@ Gcc_backend::constructor_expression (Btype *btype,
if (union_index != -1)
{
gcc_assert (TREE_CODE (type_tree) == UNION_TYPE);
- tree val = vals.front ()->get_tree ();
+ tree val = vals.front ();
for (int i = 0; i < union_index; i++)
{
gcc_assert (field != NULL_TREE);
@@ -2090,11 +1763,11 @@ Gcc_backend::constructor_expression (Btype *btype,
else
{
gcc_assert (TREE_CODE (type_tree) == RECORD_TYPE);
- for (std::vector<Bexpression *>::const_iterator p = vals.begin ();
+ for (std::vector<tree>::const_iterator p = vals.begin ();
p != vals.end (); ++p, field = DECL_CHAIN (field))
{
gcc_assert (field != NULL_TREE);
- tree val = (*p)->get_tree ();
+ tree val = (*p);
if (TREE_TYPE (field) == error_mark_node || val == error_mark_node
|| TREE_TYPE (val) == error_mark_node)
return this->error_expression ();
@@ -2125,15 +1798,14 @@ Gcc_backend::constructor_expression (Btype *btype,
if (sink != NULL_TREE)
ret = fold_build2_loc (location.gcc_location (), COMPOUND_EXPR, type_tree,
sink, ret);
- return this->make_expression (ret);
+ return ret;
}
-Bexpression *
+tree
Gcc_backend::array_constructor_expression (
- Btype *array_btype, const std::vector<unsigned long> &indexes,
- const std::vector<Bexpression *> &vals, Location location)
+ tree type_tree, const std::vector<unsigned long> &indexes,
+ const std::vector<tree> &vals, Location location)
{
- tree type_tree = array_btype->get_tree ();
if (type_tree == error_mark_node)
return this->error_expression ();
@@ -2149,7 +1821,7 @@ Gcc_backend::array_constructor_expression (
for (size_t i = 0; i < vals.size (); ++i)
{
tree index = size_int (indexes[i]);
- tree val = (vals[i])->get_tree ();
+ tree val = vals[i];
if (index == error_mark_node || val == error_mark_node)
return this->error_expression ();
@@ -2179,17 +1851,15 @@ Gcc_backend::array_constructor_expression (
if (sink != NULL_TREE)
ret = fold_build2_loc (location.gcc_location (), COMPOUND_EXPR, type_tree,
sink, ret);
- return this->make_expression (ret);
+ return ret;
}
// Return an expression for the address of BASE[INDEX].
-Bexpression *
-Gcc_backend::pointer_offset_expression (Bexpression *base, Bexpression *index,
+tree
+Gcc_backend::pointer_offset_expression (tree base_tree, tree index_tree,
Location location)
{
- tree base_tree = base->get_tree ();
- tree index_tree = index->get_tree ();
tree element_type_tree = TREE_TYPE (TREE_TYPE (base_tree));
if (base_tree == error_mark_node || TREE_TYPE (base_tree) == error_mark_node
|| index_tree == error_mark_node || element_type_tree == error_mark_node)
@@ -2202,17 +1872,15 @@ Gcc_backend::pointer_offset_expression (Bexpression *base, Bexpression *index,
index_tree, element_size);
tree ptr = fold_build2_loc (location.gcc_location (), POINTER_PLUS_EXPR,
TREE_TYPE (base_tree), base_tree, offset);
- return this->make_expression (ptr);
+ return ptr;
}
// Return an expression representing ARRAY[INDEX]
-Bexpression *
-Gcc_backend::array_index_expression (Bexpression *array, Bexpression *index,
+tree
+Gcc_backend::array_index_expression (tree array_tree, tree index_tree,
Location location)
{
- tree array_tree = array->get_tree ();
- tree index_tree = index->get_tree ();
if (array_tree == error_mark_node || TREE_TYPE (array_tree) == error_mark_node
|| index_tree == error_mark_node)
return this->error_expression ();
@@ -2229,17 +1897,15 @@ Gcc_backend::array_index_expression (Bexpression *array, Bexpression *index,
ret = fold_build2_loc (location.gcc_location (), COMPOUND_EXPR,
void_type_node, array_tree, index_tree);
- return this->make_expression (ret);
+ return ret;
}
// Create an expression for a call to FN_EXPR with FN_ARGS.
-Bexpression *
-Gcc_backend::call_expression (Bfunction *, // containing fcn for call
- Bexpression *fn_expr,
- const std::vector<Bexpression *> &fn_args,
- Bexpression *chain_expr, Location location)
+tree
+Gcc_backend::call_expression (tree, // containing fcn for call
+ tree fn, const std::vector<tree> &fn_args,
+ tree chain_expr, Location location)
{
- tree fn = fn_expr->get_tree ();
if (fn == error_mark_node || TREE_TYPE (fn) == error_mark_node)
return this->error_expression ();
@@ -2250,7 +1916,7 @@ Gcc_backend::call_expression (Bfunction *, // containing fcn for call
tree *args = nargs == 0 ? NULL : new tree[nargs];
for (size_t i = 0; i < nargs; ++i)
{
- args[i] = fn_args.at (i)->get_tree ();
+ args[i] = fn_args.at (i);
if (args[i] == error_mark_node)
return this->error_expression ();
}
@@ -2296,7 +1962,7 @@ Gcc_backend::call_expression (Bfunction *, // containing fcn for call
fn, nargs, args);
if (chain_expr)
- CALL_EXPR_STATIC_CHAIN (ret) = chain_expr->get_tree ();
+ CALL_EXPR_STATIC_CHAIN (ret) = chain_expr;
if (excess_type != NULL_TREE)
{
@@ -2306,24 +1972,23 @@ Gcc_backend::call_expression (Bfunction *, // containing fcn for call
}
delete[] args;
- return this->make_expression (ret);
+ return ret;
}
// An expression as a statement.
-Bstatement *
-Gcc_backend::expression_statement (Bfunction *, Bexpression *expr)
+tree
+Gcc_backend::expression_statement (tree, tree expr)
{
- return this->make_statement (expr->get_tree ());
+ return expr;
}
// Variable initialization.
-Bstatement *
-Gcc_backend::init_statement (Bfunction *, Bvariable *var, Bexpression *init)
+tree
+Gcc_backend::init_statement (tree, Bvariable *var, tree init_tree)
{
tree var_tree = var->get_decl ();
- tree init_tree = init->get_tree ();
if (var_tree == error_mark_node || init_tree == error_mark_node)
return this->error_statement ();
gcc_assert (TREE_CODE (var_tree) == VAR_DECL);
@@ -2347,18 +2012,16 @@ Gcc_backend::init_statement (Bfunction *, Bvariable *var, Bexpression *init)
ret = build2_loc (DECL_SOURCE_LOCATION (var_tree), COMPOUND_EXPR,
void_type_node, init_tree, ret);
- return this->make_statement (ret);
+ return ret;
}
// Assignment.
-Bstatement *
-Gcc_backend::assignment_statement (Bfunction *bfn, Bexpression *lhs,
- Bexpression *rhs, Location location)
+tree
+Gcc_backend::assignment_statement (tree bfn, tree lhs, tree rhs,
+ Location location)
{
- tree lhs_tree = lhs->get_tree ();
- tree rhs_tree = rhs->get_tree ();
- if (lhs_tree == error_mark_node || rhs_tree == error_mark_node)
+ if (lhs == error_mark_node || rhs == error_mark_node)
return this->error_statement ();
// To avoid problems with GNU ld, we don't make zero-sized
@@ -2367,28 +2030,25 @@ Gcc_backend::assignment_statement (Bfunction *bfn, Bexpression *lhs,
// expression; avoid crashes here by avoiding assignments of
// zero-sized expressions. Such assignments don't really mean
// anything anyhow.
- if (TREE_TYPE (lhs_tree) == void_type_node
- || int_size_in_bytes (TREE_TYPE (lhs_tree)) == 0
- || TREE_TYPE (rhs_tree) == void_type_node
- || int_size_in_bytes (TREE_TYPE (rhs_tree)) == 0)
+ if (TREE_TYPE (lhs) == void_type_node
+ || int_size_in_bytes (TREE_TYPE (lhs)) == 0
+ || TREE_TYPE (rhs) == void_type_node
+ || int_size_in_bytes (TREE_TYPE (rhs)) == 0)
return this->compound_statement (this->expression_statement (bfn, lhs),
this->expression_statement (bfn, rhs));
- rhs_tree = this->convert_tree (TREE_TYPE (lhs_tree), rhs_tree, location);
+ rhs = this->convert_tree (TREE_TYPE (lhs), rhs, location);
- return this->make_statement (fold_build2_loc (location.gcc_location (),
- MODIFY_EXPR, void_type_node,
- lhs_tree, rhs_tree));
+ return fold_build2_loc (location.gcc_location (), MODIFY_EXPR, void_type_node,
+ lhs, rhs);
}
// Return.
-Bstatement *
-Gcc_backend::return_statement (Bfunction *bfunction,
- const std::vector<Bexpression *> &vals,
+tree
+Gcc_backend::return_statement (tree fntree, const std::vector<tree> &vals,
Location location)
{
- tree fntree = bfunction->get_tree ();
if (fntree == error_mark_node)
return this->error_statement ();
tree result = DECL_RESULT (fntree);
@@ -2402,10 +2062,10 @@ Gcc_backend::return_statement (Bfunction *bfunction,
if (res_type == void_type_node || int_size_in_bytes (res_type) == 0)
{
tree stmt_list = NULL_TREE;
- for (std::vector<Bexpression *>::const_iterator p = vals.begin ();
+ for (std::vector<tree>::const_iterator p = vals.begin ();
p != vals.end (); p++)
{
- tree val = (*p)->get_tree ();
+ tree val = (*p);
if (val == error_mark_node)
return this->error_statement ();
append_to_statement_list (val, &stmt_list);
@@ -2413,7 +2073,7 @@ Gcc_backend::return_statement (Bfunction *bfunction,
tree ret = fold_build1_loc (location.gcc_location (), RETURN_EXPR,
void_type_node, NULL_TREE);
append_to_statement_list (ret, &stmt_list);
- return this->make_statement (stmt_list);
+ return stmt_list;
}
tree ret;
@@ -2422,12 +2082,11 @@ Gcc_backend::return_statement (Bfunction *bfunction,
void_type_node, NULL_TREE);
else if (vals.size () == 1)
{
- tree val = vals.front ()->get_tree ();
+ tree val = vals.front ();
if (val == error_mark_node)
return this->error_statement ();
- tree set
- = fold_build2_loc (location.gcc_location (), MODIFY_EXPR,
- void_type_node, result, vals.front ()->get_tree ());
+ tree set = fold_build2_loc (location.gcc_location (), MODIFY_EXPR,
+ void_type_node, result, vals.front ());
ret = fold_build1_loc (location.gcc_location (), RETURN_EXPR,
void_type_node, set);
}
@@ -2448,18 +2107,18 @@ Gcc_backend::return_statement (Bfunction *bfunction,
pop_cfun ();
tree field = TYPE_FIELDS (rettype);
- for (std::vector<Bexpression *>::const_iterator p = vals.begin ();
+ for (std::vector<tree>::const_iterator p = vals.begin ();
p != vals.end (); p++, field = DECL_CHAIN (field))
{
gcc_assert (field != NULL_TREE);
tree ref
= fold_build3_loc (location.gcc_location (), COMPONENT_REF,
TREE_TYPE (field), rettmp, field, NULL_TREE);
- tree val = (*p)->get_tree ();
+ tree val = (*p);
if (val == error_mark_node)
return this->error_statement ();
tree set = fold_build2_loc (location.gcc_location (), MODIFY_EXPR,
- void_type_node, ref, (*p)->get_tree ());
+ void_type_node, ref, (*p));
append_to_statement_list (set, &stmt_list);
}
gcc_assert (field == NULL_TREE);
@@ -2470,7 +2129,7 @@ Gcc_backend::return_statement (Bfunction *bfunction,
append_to_statement_list (ret_expr, &stmt_list);
ret = stmt_list;
}
- return this->make_statement (ret);
+ return ret;
}
// Create a statement that attempts to execute BSTAT and calls EXCEPT_STMT if an
@@ -2479,116 +2138,101 @@ Gcc_backend::return_statement (Bfunction *bfunction,
// functions. In C++, the resulting code is of this form:
// try { BSTAT; } catch { EXCEPT_STMT; } finally { FINALLY_STMT; }
-Bstatement *
-Gcc_backend::exception_handler_statement (Bstatement *bstat,
- Bstatement *except_stmt,
- Bstatement *finally_stmt,
- Location location)
+tree
+Gcc_backend::exception_handler_statement (tree try_stmt, tree except_stmt,
+ tree finally_stmt, Location location)
{
- tree stat_tree = bstat->get_tree ();
- tree except_tree = except_stmt == NULL ? NULL_TREE : except_stmt->get_tree ();
- tree finally_tree
- = finally_stmt == NULL ? NULL_TREE : finally_stmt->get_tree ();
-
- if (stat_tree == error_mark_node || except_tree == error_mark_node
- || finally_tree == error_mark_node)
+ if (try_stmt == error_mark_node || except_stmt == error_mark_node
+ || finally_stmt == error_mark_node)
return this->error_statement ();
- if (except_tree != NULL_TREE)
- stat_tree = build2_loc (location.gcc_location (), TRY_CATCH_EXPR,
- void_type_node, stat_tree,
- build2_loc (location.gcc_location (), CATCH_EXPR,
- void_type_node, NULL, except_tree));
- if (finally_tree != NULL_TREE)
- stat_tree = build2_loc (location.gcc_location (), TRY_FINALLY_EXPR,
- void_type_node, stat_tree, finally_tree);
- return this->make_statement (stat_tree);
+ if (except_stmt != NULL_TREE)
+ try_stmt = build2_loc (location.gcc_location (), TRY_CATCH_EXPR,
+ void_type_node, try_stmt,
+ build2_loc (location.gcc_location (), CATCH_EXPR,
+ void_type_node, NULL, except_stmt));
+ if (finally_stmt != NULL_TREE)
+ try_stmt = build2_loc (location.gcc_location (), TRY_FINALLY_EXPR,
+ void_type_node, try_stmt, finally_stmt);
+ return try_stmt;
}
// If.
-Bstatement *
-Gcc_backend::if_statement (Bfunction *, Bexpression *condition,
- Bblock *then_block, Bblock *else_block,
+tree
+Gcc_backend::if_statement (tree, tree cond_tree, tree then_tree, tree else_tree,
Location location)
{
- tree cond_tree = condition->get_tree ();
- tree then_tree = then_block->get_tree ();
- tree else_tree = else_block == NULL ? NULL_TREE : else_block->get_tree ();
if (cond_tree == error_mark_node || then_tree == error_mark_node
|| else_tree == error_mark_node)
return this->error_statement ();
tree ret = build3_loc (location.gcc_location (), COND_EXPR, void_type_node,
cond_tree, then_tree, else_tree);
- return this->make_statement (ret);
+ return ret;
}
// Loops
-Bexpression *
-Gcc_backend::loop_expression (Bblock *body, Location locus)
+tree
+Gcc_backend::loop_expression (tree body, Location locus)
{
- tree loop_expr_tree = fold_build1_loc (locus.gcc_location (), LOOP_EXPR,
- void_type_node, body->get_tree ());
- return this->make_expression (loop_expr_tree);
+ return fold_build1_loc (locus.gcc_location (), LOOP_EXPR, void_type_node,
+ body);
}
-Bexpression *
-Gcc_backend::exit_expression (Bexpression *condition, Location locus)
+tree
+Gcc_backend::exit_expression (tree cond_tree, Location locus)
{
- tree cond_tree = condition->get_tree ();
- tree exit_expr_tree = fold_build1_loc (locus.gcc_location (), EXIT_EXPR,
- void_type_node, cond_tree);
- return this->make_expression (exit_expr_tree);
+ return fold_build1_loc (locus.gcc_location (), EXIT_EXPR, void_type_node,
+ cond_tree);
}
// Switch.
-Bstatement *
-Gcc_backend::switch_statement (
- Bfunction *function, Bexpression *value,
- const std::vector<std::vector<Bexpression *> > &cases,
- const std::vector<Bstatement *> &statements, Location switch_location)
+tree
+Gcc_backend::switch_statement (tree decl, tree value,
+ const std::vector<std::vector<tree>> &cases,
+ const std::vector<tree> &statements,
+ Location switch_location)
{
gcc_assert (cases.size () == statements.size ());
- tree decl = function->get_tree ();
if (DECL_STRUCT_FUNCTION (decl) == NULL)
push_struct_function (decl);
else
push_cfun (DECL_STRUCT_FUNCTION (decl));
tree stmt_list = NULL_TREE;
- std::vector<std::vector<Bexpression *> >::const_iterator pc = cases.begin ();
- for (std::vector<Bstatement *>::const_iterator ps = statements.begin ();
+ std::vector<std::vector<tree>>::const_iterator pc = cases.begin ();
+ for (std::vector<tree>::const_iterator ps = statements.begin ();
ps != statements.end (); ++ps, ++pc)
{
if (pc->empty ())
{
- location_t loc = (*ps != NULL ? EXPR_LOCATION ((*ps)->get_tree ())
- : UNKNOWN_LOCATION);
+ location_t loc
+ = (*ps != NULL ? EXPR_LOCATION (*ps) : UNKNOWN_LOCATION);
tree label = create_artificial_label (loc);
tree c = build_case_label (NULL_TREE, NULL_TREE, label);
append_to_statement_list (c, &stmt_list);
}
else
{
- for (std::vector<Bexpression *>::const_iterator pcv = pc->begin ();
+ for (std::vector<tree>::const_iterator pcv = pc->begin ();
pcv != pc->end (); ++pcv)
{
- tree t = (*pcv)->get_tree ();
+ tree t = (*pcv);
if (t == error_mark_node)
return this->error_statement ();
location_t loc = EXPR_LOCATION (t);
tree label = create_artificial_label (loc);
- tree c = build_case_label ((*pcv)->get_tree (), NULL_TREE, label);
+ tree c = build_case_label ((*pcv), NULL_TREE, label);
append_to_statement_list (c, &stmt_list);
}
}
if (*ps != NULL)
{
- tree t = (*ps)->get_tree ();
+ tree t = (*ps);
if (t == error_mark_node)
return this->error_statement ();
append_to_statement_list (t, &stmt_list);
@@ -2596,25 +2240,25 @@ Gcc_backend::switch_statement (
}
pop_cfun ();
- tree tv = value->get_tree ();
+ tree tv = value;
if (tv == error_mark_node)
return this->error_statement ();
tree t = build2_loc (switch_location.gcc_location (), SWITCH_EXPR, NULL_TREE,
tv, stmt_list);
- return this->make_statement (t);
+ return t;
}
// Pair of statements.
-Bstatement *
-Gcc_backend::compound_statement (Bstatement *s1, Bstatement *s2)
+tree
+Gcc_backend::compound_statement (tree s1, tree s2)
{
tree stmt_list = NULL_TREE;
- tree t = s1->get_tree ();
+ tree t = s1;
if (t == error_mark_node)
return this->error_statement ();
append_to_statement_list (t, &stmt_list);
- t = s2->get_tree ();
+ t = s2;
if (t == error_mark_node)
return this->error_statement ();
append_to_statement_list (t, &stmt_list);
@@ -2624,24 +2268,24 @@ Gcc_backend::compound_statement (Bstatement *s1, Bstatement *s2)
if (stmt_list == NULL_TREE)
stmt_list = integer_zero_node;
- return this->make_statement (stmt_list);
+ return stmt_list;
}
// List of statements.
-Bstatement *
-Gcc_backend::statement_list (const std::vector<Bstatement *> &statements)
+tree
+Gcc_backend::statement_list (const std::vector<tree> &statements)
{
tree stmt_list = NULL_TREE;
- for (std::vector<Bstatement *>::const_iterator p = statements.begin ();
+ for (std::vector<tree>::const_iterator p = statements.begin ();
p != statements.end (); ++p)
{
- tree t = (*p)->get_tree ();
+ tree t = (*p);
if (t == error_mark_node)
return this->error_statement ();
append_to_statement_list (t, &stmt_list);
}
- return this->make_statement (stmt_list);
+ return stmt_list;
}
// Make a block. For some reason gcc uses a dual structure for
@@ -2649,15 +2293,14 @@ Gcc_backend::statement_list (const std::vector<Bstatement *> &statements)
// BIND_EXPR node points to the BLOCK node, we store the BIND_EXPR in
// the Bblock.
-Bblock *
-Gcc_backend::block (Bfunction *function, Bblock *enclosing,
+tree
+Gcc_backend::block (tree fndecl, tree enclosing,
const std::vector<Bvariable *> &vars,
Location start_location, Location)
{
tree block_tree = make_node (BLOCK);
if (enclosing == NULL)
{
- tree fndecl = function->get_tree ();
gcc_assert (fndecl != NULL_TREE);
// We may have already created a block for local variables when
@@ -2680,8 +2323,7 @@ Gcc_backend::block (Bfunction *function, Bblock *enclosing,
}
else
{
- tree superbind_tree = enclosing->get_tree ();
- tree superblock_tree = BIND_EXPR_BLOCK (superbind_tree);
+ tree superblock_tree = BIND_EXPR_BLOCK (enclosing);
gcc_assert (TREE_CODE (superblock_tree) == BLOCK);
BLOCK_SUPERCONTEXT (block_tree) = superblock_tree;
@@ -2708,37 +2350,35 @@ Gcc_backend::block (Bfunction *function, Bblock *enclosing,
= build3_loc (start_location.gcc_location (), BIND_EXPR, void_type_node,
BLOCK_VARS (block_tree), NULL_TREE, block_tree);
TREE_SIDE_EFFECTS (bind_tree) = 1;
- return new Bblock (bind_tree);
+ return bind_tree;
}
// Add statements to a block.
void
-Gcc_backend::block_add_statements (Bblock *bblock,
- const std::vector<Bstatement *> &statements)
+Gcc_backend::block_add_statements (tree bind_tree,
+ const std::vector<tree> &statements)
{
tree stmt_list = NULL_TREE;
- for (std::vector<Bstatement *>::const_iterator p = statements.begin ();
+ for (std::vector<tree>::const_iterator p = statements.begin ();
p != statements.end (); ++p)
{
- tree s = (*p)->get_tree ();
+ tree s = (*p);
if (s != error_mark_node)
append_to_statement_list (s, &stmt_list);
}
- tree bind_tree = bblock->get_tree ();
gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
BIND_EXPR_BODY (bind_tree) = stmt_list;
}
// Return a block as a statement.
-Bstatement *
-Gcc_backend::block_statement (Bblock *bblock)
+tree
+Gcc_backend::block_statement (tree bind_tree)
{
- tree bind_tree = bblock->get_tree ();
gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
- return this->make_statement (bind_tree);
+ return bind_tree;
}
// This is not static because we declare it with GTY(()) in rust-c.h.
@@ -2839,11 +2479,10 @@ Gcc_backend::convert_tree (tree type_tree, tree expr_tree, Location location)
Bvariable *
Gcc_backend::global_variable (const std::string &var_name,
- const std::string &asm_name, Btype *btype,
+ const std::string &asm_name, tree type_tree,
bool is_external, bool is_hidden,
bool in_unique_section, Location location)
{
- tree type_tree = btype->get_tree ();
if (type_tree == error_mark_node)
return this->error_variable ();
@@ -2881,9 +2520,8 @@ Gcc_backend::global_variable (const std::string &var_name,
// Set the initial value of a global variable.
void
-Gcc_backend::global_variable_set_init (Bvariable *var, Bexpression *expr)
+Gcc_backend::global_variable_set_init (Bvariable *var, tree expr_tree)
{
- tree expr_tree = expr->get_tree ();
if (expr_tree == error_mark_node)
return;
gcc_assert (TREE_CONSTANT (expr_tree));
@@ -2906,16 +2544,15 @@ Gcc_backend::global_variable_set_init (Bvariable *var, Bexpression *expr)
// Make a local variable.
Bvariable *
-Gcc_backend::local_variable (Bfunction *function, const std::string &name,
- Btype *btype, Bvariable *decl_var,
+Gcc_backend::local_variable (tree function, const std::string &name,
+ tree type_tree, Bvariable *decl_var,
bool is_address_taken, Location location)
{
- tree type_tree = btype->get_tree ();
if (type_tree == error_mark_node)
return this->error_variable ();
tree decl = build_decl (location.gcc_location (), VAR_DECL,
get_identifier_from_string (name), type_tree);
- DECL_CONTEXT (decl) = function->get_tree ();
+ DECL_CONTEXT (decl) = function;
TREE_USED (decl) = 1;
if (is_address_taken)
TREE_ADDRESSABLE (decl) = 1;
@@ -2931,16 +2568,15 @@ Gcc_backend::local_variable (Bfunction *function, const std::string &name,
// Make a function parameter variable.
Bvariable *
-Gcc_backend::parameter_variable (Bfunction *function, const std::string &name,
- Btype *btype, bool is_address_taken,
+Gcc_backend::parameter_variable (tree function, const std::string &name,
+ tree type_tree, bool is_address_taken,
Location location)
{
- tree type_tree = btype->get_tree ();
if (type_tree == error_mark_node)
return this->error_variable ();
tree decl = build_decl (location.gcc_location (), PARM_DECL,
get_identifier_from_string (name), type_tree);
- DECL_CONTEXT (decl) = function->get_tree ();
+ DECL_CONTEXT (decl) = function;
DECL_ARG_TYPE (decl) = type_tree;
TREE_USED (decl) = 1;
if (is_address_taken)
@@ -2952,16 +2588,13 @@ Gcc_backend::parameter_variable (Bfunction *function, const std::string &name,
// Make a static chain variable.
Bvariable *
-Gcc_backend::static_chain_variable (Bfunction *function,
- const std::string &name, Btype *btype,
- Location location)
+Gcc_backend::static_chain_variable (tree fndecl, const std::string &name,
+ tree type_tree, Location location)
{
- tree type_tree = btype->get_tree ();
if (type_tree == error_mark_node)
return this->error_variable ();
tree decl = build_decl (location.gcc_location (), PARM_DECL,
get_identifier_from_string (name), type_tree);
- tree fndecl = function->get_tree ();
DECL_CONTEXT (decl) = fndecl;
DECL_ARG_TYPE (decl) = type_tree;
TREE_USED (decl) = 1;
@@ -2987,17 +2620,13 @@ Gcc_backend::static_chain_variable (Bfunction *function,
// Make a temporary variable.
Bvariable *
-Gcc_backend::temporary_variable (Bfunction *function, Bblock *bblock,
- Btype *btype, Bexpression *binit,
- bool is_address_taken, Location location,
- Bstatement **pstatement)
-{
- gcc_assert (function != NULL);
- tree decl = function->get_tree ();
- tree type_tree = btype->get_tree ();
- tree init_tree = binit == NULL ? NULL_TREE : binit->get_tree ();
+Gcc_backend::temporary_variable (tree fndecl, tree bind_tree, tree type_tree,
+ tree init_tree, bool is_address_taken,
+ Location location, tree *pstatement)
+{
+ gcc_assert (fndecl != NULL_TREE);
if (type_tree == error_mark_node || init_tree == error_mark_node
- || decl == error_mark_node)
+ || fndecl == error_mark_node)
{
*pstatement = this->error_statement ();
return this->error_variable ();
@@ -3007,26 +2636,25 @@ Gcc_backend::temporary_variable (Bfunction *function, Bblock *bblock,
// We can only use create_tmp_var if the type is not addressable.
if (!TREE_ADDRESSABLE (type_tree))
{
- if (DECL_STRUCT_FUNCTION (decl) == NULL)
- push_struct_function (decl);
+ if (DECL_STRUCT_FUNCTION (fndecl) == NULL)
+ push_struct_function (fndecl);
else
- push_cfun (DECL_STRUCT_FUNCTION (decl));
+ push_cfun (DECL_STRUCT_FUNCTION (fndecl));
var = create_tmp_var (type_tree, "RUSTTMP");
pop_cfun ();
}
else
{
- gcc_assert (bblock != NULL);
+ gcc_assert (bind_tree != NULL_TREE);
var = build_decl (location.gcc_location (), VAR_DECL,
create_tmp_var_name ("RUSTTMP"), type_tree);
DECL_ARTIFICIAL (var) = 1;
DECL_IGNORED_P (var) = 1;
TREE_USED (var) = 1;
- DECL_CONTEXT (var) = decl;
+ DECL_CONTEXT (var) = fndecl;
// We have to add this variable to the BLOCK and the BIND_EXPR.
- tree bind_tree = bblock->get_tree ();
gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
tree block_tree = BIND_EXPR_BLOCK (bind_tree);
gcc_assert (TREE_CODE (block_tree) == BLOCK);
@@ -3035,24 +2663,23 @@ Gcc_backend::temporary_variable (Bfunction *function, Bblock *bblock,
BIND_EXPR_VARS (bind_tree) = BLOCK_VARS (block_tree);
}
- if (this->type_size (btype) != 0 && init_tree != NULL_TREE
+ if (this->type_size (type_tree) != 0 && init_tree != NULL_TREE
&& TREE_TYPE (init_tree) != void_type_node)
DECL_INITIAL (var) = this->convert_tree (type_tree, init_tree, location);
if (is_address_taken)
TREE_ADDRESSABLE (var) = 1;
- *pstatement = this->make_statement (
- build1_loc (location.gcc_location (), DECL_EXPR, void_type_node, var));
+ *pstatement
+ = build1_loc (location.gcc_location (), DECL_EXPR, void_type_node, var);
// For a zero sized type, don't initialize VAR with BINIT, but still
// evaluate BINIT for its side effects.
if (init_tree != NULL_TREE
- && (this->type_size (btype) == 0
+ && (this->type_size (type_tree) == 0
|| TREE_TYPE (init_tree) == void_type_node))
- *pstatement
- = this->compound_statement (this->expression_statement (function, binit),
- *pstatement);
+ *pstatement = this->compound_statement (
+ this->expression_statement (fndecl, init_tree), *pstatement);
return new Bvariable (var);
}
@@ -3062,11 +2689,10 @@ Gcc_backend::temporary_variable (Bfunction *function, Bblock *bblock,
Bvariable *
Gcc_backend::implicit_variable (const std::string &name,
- const std::string &asm_name, Btype *type,
+ const std::string &asm_name, tree type_tree,
bool is_hidden, bool is_constant,
bool is_common, int64_t alignment)
{
- tree type_tree = type->get_tree ();
if (type_tree == error_mark_node)
return this->error_variable ();
@@ -3117,15 +2743,10 @@ Gcc_backend::implicit_variable (const std::string &name,
void
Gcc_backend::implicit_variable_set_init (Bvariable *var, const std::string &,
- Btype *, bool, bool, bool is_common,
- Bexpression *init)
+ tree, bool, bool, bool is_common,
+ tree init_tree)
{
tree decl = var->get_decl ();
- tree init_tree;
- if (init == NULL)
- init_tree = NULL_TREE;
- else
- init_tree = init->get_tree ();
if (decl == error_mark_node || init_tree == error_mark_node)
return;
@@ -3149,9 +2770,8 @@ Gcc_backend::implicit_variable_set_init (Bvariable *var, const std::string &,
Bvariable *
Gcc_backend::implicit_variable_reference (const std::string &name,
const std::string &asm_name,
- Btype *btype)
+ tree type_tree)
{
- tree type_tree = btype->get_tree ();
if (type_tree == error_mark_node)
return this->error_variable ();
@@ -3172,9 +2792,9 @@ Gcc_backend::implicit_variable_reference (const std::string &name,
Bvariable *
Gcc_backend::immutable_struct (const std::string &name,
const std::string &asm_name, bool is_hidden,
- bool is_common, Btype *btype, Location location)
+ bool is_common, tree type_tree,
+ Location location)
{
- tree type_tree = btype->get_tree ();
if (type_tree == error_mark_node)
return this->error_variable ();
gcc_assert (TREE_CODE (type_tree) == RECORD_TYPE);
@@ -3218,11 +2838,10 @@ Gcc_backend::immutable_struct (const std::string &name,
void
Gcc_backend::immutable_struct_set_init (Bvariable *var, const std::string &,
- bool, bool is_common, Btype *, Location,
- Bexpression *initializer)
+ bool, bool is_common, tree, Location,
+ tree init_tree)
{
tree decl = var->get_decl ();
- tree init_tree = initializer->get_tree ();
if (decl == error_mark_node || init_tree == error_mark_node)
return;
@@ -3249,9 +2868,8 @@ Gcc_backend::immutable_struct_set_init (Bvariable *var, const std::string &,
Bvariable *
Gcc_backend::immutable_struct_reference (const std::string &name,
const std::string &asm_name,
- Btype *btype, Location location)
+ tree type_tree, Location location)
{
- tree type_tree = btype->get_tree ();
if (type_tree == error_mark_node)
return this->error_variable ();
gcc_assert (TREE_CODE (type_tree) == RECORD_TYPE);
@@ -3271,14 +2889,12 @@ Gcc_backend::immutable_struct_reference (const std::string &name,
// Make a label.
-Blabel *
-Gcc_backend::label (Bfunction *function, const std::string &name,
- Location location)
+tree
+Gcc_backend::label (tree func_tree, const std::string &name, Location location)
{
tree decl;
if (name.empty ())
{
- tree func_tree = function->get_tree ();
if (DECL_STRUCT_FUNCTION (func_tree) == NULL)
push_struct_function (func_tree);
else
@@ -3293,56 +2909,50 @@ Gcc_backend::label (Bfunction *function, const std::string &name,
tree id = get_identifier_from_string (name);
decl
= build_decl (location.gcc_location (), LABEL_DECL, id, void_type_node);
- DECL_CONTEXT (decl) = function->get_tree ();
+ DECL_CONTEXT (decl) = func_tree;
}
- return new Blabel (decl);
+ return decl;
}
// Make a statement which defines a label.
-Bstatement *
-Gcc_backend::label_definition_statement (Blabel *label)
+tree
+Gcc_backend::label_definition_statement (tree label)
{
- tree lab = label->get_tree ();
- tree ret = fold_build1_loc (DECL_SOURCE_LOCATION (lab), LABEL_EXPR,
- void_type_node, lab);
- return this->make_statement (ret);
+ return fold_build1_loc (DECL_SOURCE_LOCATION (label), LABEL_EXPR,
+ void_type_node, label);
}
// Make a goto statement.
-Bstatement *
-Gcc_backend::goto_statement (Blabel *label, Location location)
+tree
+Gcc_backend::goto_statement (tree label, Location location)
{
- tree lab = label->get_tree ();
- tree ret = fold_build1_loc (location.gcc_location (), GOTO_EXPR,
- void_type_node, lab);
- return this->make_statement (ret);
+ return fold_build1_loc (location.gcc_location (), GOTO_EXPR, void_type_node,
+ label);
}
// Get the address of a label.
-Bexpression *
-Gcc_backend::label_address (Blabel *label, Location location)
+tree
+Gcc_backend::label_address (tree label, Location location)
{
- tree lab = label->get_tree ();
- TREE_USED (lab) = 1;
- TREE_ADDRESSABLE (lab) = 1;
+ TREE_USED (label) = 1;
+ TREE_ADDRESSABLE (label) = 1;
tree ret
= fold_convert_loc (location.gcc_location (), ptr_type_node,
build_fold_addr_expr_loc (location.gcc_location (),
- lab));
- return this->make_expression (ret);
+ label));
+ return ret;
}
// Declare or define a new function.
-Bfunction *
-Gcc_backend::function (Btype *fntype, const std::string &name,
+tree
+Gcc_backend::function (tree functype, const std::string &name,
const std::string &asm_name, unsigned int flags,
Location location)
{
- tree functype = fntype->get_tree ();
if (functype != error_mark_node)
{
gcc_assert (FUNCTION_POINTER_TYPE_P (functype));
@@ -3386,7 +2996,7 @@ Gcc_backend::function (Btype *fntype, const std::string &name,
TREE_READONLY (decl) = 1;
rust_preserve_from_gc (decl);
- return new Bfunction (decl);
+ return decl;
}
// Create a statement that runs all deferred calls for FUNCTION. This should
@@ -3394,39 +3004,34 @@ Gcc_backend::function (Btype *fntype, const std::string &name,
// finish:
// try { UNDEFER; } catch { CHECK_DEFER; goto finish; }
-Bstatement *
-Gcc_backend::function_defer_statement (Bfunction *function,
- Bexpression *undefer, Bexpression *defer,
- Location location)
+tree
+Gcc_backend::function_defer_statement (tree function, tree undefer_tree,
+ tree defer_tree, Location location)
{
- tree undefer_tree = undefer->get_tree ();
- tree defer_tree = defer->get_tree ();
- tree fntree = function->get_tree ();
-
if (undefer_tree == error_mark_node || defer_tree == error_mark_node
- || fntree == error_mark_node)
+ || function == error_mark_node)
return this->error_statement ();
- if (DECL_STRUCT_FUNCTION (fntree) == NULL)
- push_struct_function (fntree);
+ if (DECL_STRUCT_FUNCTION (function) == NULL)
+ push_struct_function (function);
else
- push_cfun (DECL_STRUCT_FUNCTION (fntree));
+ push_cfun (DECL_STRUCT_FUNCTION (function));
tree stmt_list = NULL;
- Blabel *blabel = this->label (function, "", location);
- Bstatement *label_def = this->label_definition_statement (blabel);
- append_to_statement_list (label_def->get_tree (), &stmt_list);
+ tree label = this->label (function, "", location);
+ tree label_def = this->label_definition_statement (label);
+ append_to_statement_list (label_def, &stmt_list);
- Bstatement *jump_stmt = this->goto_statement (blabel, location);
- tree jump = jump_stmt->get_tree ();
- tree catch_body = build2 (COMPOUND_EXPR, void_type_node, defer_tree, jump);
+ tree jump_stmt = this->goto_statement (label, location);
+ tree catch_body
+ = build2 (COMPOUND_EXPR, void_type_node, defer_tree, jump_stmt);
catch_body = build2 (CATCH_EXPR, void_type_node, NULL, catch_body);
tree try_catch
= build2 (TRY_CATCH_EXPR, void_type_node, undefer_tree, catch_body);
append_to_statement_list (try_catch, &stmt_list);
pop_cfun ();
- return this->make_statement (stmt_list);
+ return stmt_list;
}
// Record PARAM_VARS as the variables to use for the parameters of FUNCTION.
@@ -3434,10 +3039,9 @@ Gcc_backend::function_defer_statement (Bfunction *function,
bool
Gcc_backend::function_set_parameters (
- Bfunction *function, const std::vector<Bvariable *> &param_vars)
+ tree function, const std::vector<Bvariable *> &param_vars)
{
- tree func_tree = function->get_tree ();
- if (func_tree == error_mark_node)
+ if (function == error_mark_node)
return false;
tree params = NULL_TREE;
@@ -3450,28 +3054,25 @@ Gcc_backend::function_set_parameters (
pp = &DECL_CHAIN (*pp);
}
*pp = NULL_TREE;
- DECL_ARGUMENTS (func_tree) = params;
+ DECL_ARGUMENTS (function) = params;
return true;
}
// Set the function body for FUNCTION using the code in CODE_BLOCK.
bool
-Gcc_backend::function_set_body (Bfunction *function, Bstatement *code_stmt)
+Gcc_backend::function_set_body (tree function, tree code_stmt)
{
- tree func_tree = function->get_tree ();
- tree code = code_stmt->get_tree ();
-
- if (func_tree == error_mark_node || code == error_mark_node)
+ if (function == error_mark_node || code_stmt == error_mark_node)
return false;
- DECL_SAVED_TREE (func_tree) = code;
+ DECL_SAVED_TREE (function) = code_stmt;
return true;
}
// Look up a named built-in function in the current backend implementation.
// Returns NULL if no built-in function by that name exists.
-Bfunction *
+tree
Gcc_backend::lookup_gcc_builtin (const std::string &name)
{
if (this->builtin_functions_.count (name) != 0)
@@ -3479,7 +3080,7 @@ Gcc_backend::lookup_gcc_builtin (const std::string &name)
return NULL;
}
-Bfunction *
+tree
Gcc_backend::lookup_builtin_by_rust_name (const std::string &name)
{
auto it = rust_intrinsic_to_gcc_builtin.find (name);
@@ -3495,9 +3096,8 @@ Gcc_backend::lookup_builtin_by_rust_name (const std::string &name)
void
Gcc_backend::write_global_definitions (
- const std::vector<Btype *> &type_decls,
- const std::vector<Bexpression *> &constant_decls,
- const std::vector<Bfunction *> &function_decls,
+ const std::vector<tree> &type_decls, const std::vector<tree> &constant_decls,
+ const std::vector<tree> &function_decls,
const std::vector<Bvariable *> &variable_decls)
{
size_t count_definitions = type_decls.size () + constant_decls.size ()
@@ -3519,10 +3119,10 @@ Gcc_backend::write_global_definitions (
}
}
- for (std::vector<Btype *>::const_iterator p = type_decls.begin ();
+ for (std::vector<tree>::const_iterator p = type_decls.begin ();
p != type_decls.end (); ++p)
{
- tree type_tree = (*p)->get_tree ();
+ tree type_tree = (*p);
if (type_tree != error_mark_node && IS_TYPE_OR_DECL_P (type_tree))
{
defs[i] = TYPE_NAME (type_tree);
@@ -3531,20 +3131,20 @@ Gcc_backend::write_global_definitions (
++i;
}
}
- for (std::vector<Bexpression *>::const_iterator p = constant_decls.begin ();
+ for (std::vector<tree>::const_iterator p = constant_decls.begin ();
p != constant_decls.end (); ++p)
{
- if ((*p)->get_tree () != error_mark_node)
+ if ((*p) != error_mark_node)
{
- defs[i] = (*p)->get_tree ();
+ defs[i] = (*p);
rust_preserve_from_gc (defs[i]);
++i;
}
}
- for (std::vector<Bfunction *>::const_iterator p = function_decls.begin ();
+ for (std::vector<tree>::const_iterator p = function_decls.begin ();
p != function_decls.end (); ++p)
{
- tree decl = (*p)->get_tree ();
+ tree decl = (*p);
if (decl != error_mark_node)
{
rust_preserve_from_gc (decl);
@@ -3592,7 +3192,7 @@ Gcc_backend::define_builtin (const std::string rust_name,
if ((flags & builtin_novops) != 0)
DECL_IS_NOVOPS (decl) = 1;
set_builtin_decl (bcode, decl, true);
- this->builtin_functions_[name] = this->make_function (decl);
+ this->builtin_functions_[name] = decl;
if (libname != NULL)
{
decl = add_builtin_function (libname, fntype, bcode, BUILT_IN_NORMAL,
@@ -3603,7 +3203,7 @@ Gcc_backend::define_builtin (const std::string rust_name,
TREE_THIS_VOLATILE (decl) = 1;
if ((flags & builtin_novops) != 0)
DECL_IS_NOVOPS (decl) = 1;
- this->builtin_functions_[libname] = this->make_function (decl);
+ this->builtin_functions_[libname] = decl;
}
rust_intrinsic_to_gcc_builtin[rust_name] = name;
diff --git a/gcc/rust/typecheck/rust-autoderef.h b/gcc/rust/typecheck/rust-autoderef.h
index a4799ec..db34755 100644
--- a/gcc/rust/typecheck/rust-autoderef.h
+++ b/gcc/rust/typecheck/rust-autoderef.h
@@ -68,6 +68,47 @@ private:
const TyTy::BaseType *expected;
};
+class Adjuster
+{
+public:
+ Adjuster (const TyTy::BaseType *ty) : base (ty) {}
+
+ TyTy::BaseType *adjust_type (std::vector<Adjustment> adjustments)
+ {
+ TyTy::BaseType *ty = base->clone ();
+ for (auto &adjustment : adjustments)
+ {
+ switch (adjustment.get_type ())
+ {
+ case Resolver::Adjustment::AdjustmentType::IMM_REF:
+ ty = new TyTy::ReferenceType (ty->get_ref (),
+ TyTy::TyVar (ty->get_ref ()),
+ Mutability::Imm);
+ break;
+
+ case Resolver::Adjustment::AdjustmentType::MUT_REF:
+ ty = new TyTy::ReferenceType (ty->get_ref (),
+ TyTy::TyVar (ty->get_ref ()),
+ Mutability::Mut);
+ break;
+
+ case Resolver::Adjustment::AdjustmentType::DEREF_REF:
+ // FIXME this really needs to support deref lang-item operator
+ // overloads
+ rust_assert (ty->get_kind () == TyTy::TypeKind::REF);
+ const TyTy::ReferenceType *rr
+ = static_cast<const TyTy::ReferenceType *> (ty);
+ ty = rr->get_base ();
+ break;
+ }
+ }
+ return ty;
+ }
+
+private:
+ const TyTy::BaseType *base;
+};
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-const-fold-base.h b/gcc/rust/typecheck/rust-hir-const-fold-base.h
index 9cbf1ab..0b41053 100644
--- a/gcc/rust/typecheck/rust-hir-const-fold-base.h
+++ b/gcc/rust/typecheck/rust-hir-const-fold-base.h
@@ -56,7 +56,7 @@ public:
virtual void visit (HIR::LazyBooleanExpr &) override {}
virtual void visit (HIR::TypeCastExpr &) override {}
virtual void visit (HIR::AssignmentExpr &) override {}
-
+ virtual void visit (HIR::CompoundAssignmentExpr &) override {}
virtual void visit (HIR::GroupedExpr &) override {}
virtual void visit (HIR::ArrayElemsValues &) override {}
diff --git a/gcc/rust/typecheck/rust-hir-const-fold-ctx.h b/gcc/rust/typecheck/rust-hir-const-fold-ctx.h
index d330ac8..a3f5a16 100644
--- a/gcc/rust/typecheck/rust-hir-const-fold-ctx.h
+++ b/gcc/rust/typecheck/rust-hir-const-fold-ctx.h
@@ -36,15 +36,15 @@ public:
::Backend *get_backend () { return backend; }
- bool lookup_const (HirId id, Bexpression **expr);
+ bool lookup_const (HirId id, tree *expr);
- void insert_const (HirId, Bexpression *expr);
+ void insert_const (HirId, tree expr);
private:
Context (::Backend *backend);
::Backend *backend;
- std::map<HirId, Bexpression *> ctx;
+ std::map<HirId, tree> ctx;
};
} // namespace ConstFold
diff --git a/gcc/rust/typecheck/rust-hir-const-fold.cc b/gcc/rust/typecheck/rust-hir-const-fold.cc
index a2dd03f..6acedd1 100644
--- a/gcc/rust/typecheck/rust-hir-const-fold.cc
+++ b/gcc/rust/typecheck/rust-hir-const-fold.cc
@@ -41,7 +41,7 @@ Context::get ()
}
bool
-Context::lookup_const (HirId id, Bexpression **expr)
+Context::lookup_const (HirId id, tree *expr)
{
auto it = ctx.find (id);
if (it == ctx.end ())
@@ -52,7 +52,7 @@ Context::lookup_const (HirId id, Bexpression **expr)
}
void
-Context::insert_const (HirId id, Bexpression *expr)
+Context::insert_const (HirId id, tree expr)
{
rust_assert (ctx.find (id) == ctx.end ());
ctx[id] = expr;
@@ -75,7 +75,7 @@ ConstFoldArrayElems::visit (HIR::ArrayElemsValues &elems)
{
unsigned long index = 0;
std::vector<unsigned long> indices;
- std::vector<Bexpression *> values;
+ std::vector<tree> values;
TyTy::BaseType *tyty = nullptr;
if (!tyctx->lookup_type (expr.get_mappings ().get_hirid (), &tyty))
@@ -85,7 +85,7 @@ ConstFoldArrayElems::visit (HIR::ArrayElemsValues &elems)
return;
}
- Btype *btype = ConstFoldType::fold (tyty, ctx->get_backend ());
+ tree type = ConstFoldType::fold (tyty, ctx->get_backend ());
for (auto &value : elems.get_values ())
{
@@ -94,7 +94,7 @@ ConstFoldArrayElems::visit (HIR::ArrayElemsValues &elems)
}
folded
- = ctx->get_backend ()->array_constructor_expression (btype, indices, values,
+ = ctx->get_backend ()->array_constructor_expression (type, indices, values,
expr.get_locus ());
}
@@ -102,7 +102,7 @@ void
ConstFoldArrayElems::visit (HIR::ArrayElemsCopied &elems)
{
std::vector<unsigned long> indices;
- std::vector<Bexpression *> values;
+ std::vector<tree> values;
TyTy::BaseType *tyty = nullptr;
if (!tyctx->lookup_type (expr.get_mappings ().get_hirid (), &tyty))
@@ -112,12 +112,12 @@ ConstFoldArrayElems::visit (HIR::ArrayElemsCopied &elems)
return;
}
- Btype *btype = ConstFoldType::fold (tyty, ctx->get_backend ());
- Bexpression *elem = ConstFoldExpr::fold (elems.get_elem_to_copy ());
+ tree type = ConstFoldType::fold (tyty, ctx->get_backend ());
+ tree elem = ConstFoldExpr::fold (elems.get_elem_to_copy ());
// num copies expr was already folded in rust-hir-type-check-expr; lookup the
// earlier result
- Bexpression *num_copies_expr = ctx->get_backend ()->error_expression ();
+ tree num_copies_expr = ctx->get_backend ()->error_expression ();
ctx->lookup_const (elems.get_num_copies_expr ()->get_mappings ().get_hirid (),
&num_copies_expr);
@@ -132,7 +132,7 @@ ConstFoldArrayElems::visit (HIR::ArrayElemsCopied &elems)
}
folded
- = ctx->get_backend ()->array_constructor_expression (btype, indices, values,
+ = ctx->get_backend ()->array_constructor_expression (type, indices, values,
expr.get_locus ());
}
diff --git a/gcc/rust/typecheck/rust-hir-const-fold.h b/gcc/rust/typecheck/rust-hir-const-fold.h
index 2bf0f2c..c965e25 100644
--- a/gcc/rust/typecheck/rust-hir-const-fold.h
+++ b/gcc/rust/typecheck/rust-hir-const-fold.h
@@ -28,7 +28,7 @@ namespace ConstFold {
class ConstFoldType : public TyTy::TyVisitor
{
public:
- static Btype *fold (TyTy::BaseType *type, ::Backend *backend)
+ static tree fold (TyTy::BaseType *type, ::Backend *backend)
{
ConstFoldType folder (backend);
type->accept_vis (folder);
@@ -43,13 +43,37 @@ public:
void visit (TyTy::ArrayType &type) override
{
- Btype *element_ty = ConstFoldType::fold (type.get_element_type (), backend);
+ tree element_ty = ConstFoldType::fold (type.get_element_type (), backend);
translated = backend->array_type (element_ty, type.get_capacity ());
}
- void visit (TyTy::ReferenceType &) override { gcc_unreachable (); }
+ void visit (TyTy::ReferenceType &type) override
+ {
+ tree base_compiled_type = ConstFoldType::fold (type.get_base (), backend);
+ if (type.is_mutable ())
+ {
+ translated = backend->reference_type (base_compiled_type);
+ }
+ else
+ {
+ auto base = backend->immutable_type (base_compiled_type);
+ translated = backend->reference_type (base);
+ }
+ }
- void visit (TyTy::PointerType &) override { gcc_unreachable (); }
+ void visit (TyTy::PointerType &type) override
+ {
+ tree base_compiled_type = ConstFoldType::fold (type.get_base (), backend);
+ if (type.is_mutable ())
+ {
+ translated = backend->pointer_type (base_compiled_type);
+ }
+ else
+ {
+ auto base = backend->immutable_type (base_compiled_type);
+ translated = backend->pointer_type (base);
+ }
+ }
void visit (TyTy::ParamType &) override { gcc_unreachable (); }
@@ -188,7 +212,7 @@ public:
void visit (TyTy::StrType &) override
{
- Btype *raw_str = backend->raw_str_type ();
+ tree raw_str = backend->raw_str_type ();
translated
= backend->named_type ("str", raw_str, Linemap::predeclared_location ());
}
@@ -205,7 +229,7 @@ private:
{}
::Backend *backend;
- ::Btype *translated;
+ ::tree translated;
};
class ConstFoldItem : public ConstFoldBase
@@ -213,7 +237,7 @@ class ConstFoldItem : public ConstFoldBase
using ConstFoldBase::visit;
public:
- static Bexpression *fold (HIR::Item &item)
+ static tree fold (HIR::Item &item)
{
ConstFoldItem folder;
item.accept_vis (folder);
@@ -234,7 +258,7 @@ private:
: ConstFoldBase (), folded (ctx->get_backend ()->error_expression ())
{}
- Bexpression *folded;
+ tree folded;
};
class ConstFoldArrayElems : public ConstFoldBase
@@ -242,7 +266,7 @@ class ConstFoldArrayElems : public ConstFoldBase
using ConstFoldBase::visit;
public:
- static Bexpression *fold (HIR::ArrayExpr &expr)
+ static tree fold (HIR::ArrayExpr &expr)
{
ConstFoldArrayElems folder (expr);
HIR::ArrayElems *elems = expr.get_internal_elements ();
@@ -259,7 +283,7 @@ private:
expr (expr)
{}
- Bexpression *folded;
+ tree folded;
HIR::ArrayExpr &expr;
};
@@ -268,7 +292,7 @@ class ConstFoldExpr : public ConstFoldBase
using ConstFoldBase::visit;
public:
- static Bexpression *fold (HIR::Expr *expr)
+ static tree fold (HIR::Expr *expr)
{
ConstFoldExpr folder;
expr->accept_vis (folder);
@@ -345,7 +369,7 @@ public:
return;
}
- Btype *type = ConstFoldType::fold (tyty, ctx->get_backend ());
+ tree type = ConstFoldType::fold (tyty, ctx->get_backend ());
folded
= ctx->get_backend ()->integer_constant_expression (type, ival);
}
@@ -376,7 +400,7 @@ public:
return;
}
- Btype *type = ConstFoldType::fold (tyty, ctx->get_backend ());
+ tree type = ConstFoldType::fold (tyty, ctx->get_backend ());
folded = ctx->get_backend ()->float_constant_expression (type, fval);
}
return;
@@ -429,19 +453,51 @@ public:
void visit (HIR::ArrayIndexExpr &expr) override
{
- Bexpression *array = ConstFoldExpr::fold (expr.get_array_expr ());
- Bexpression *index = ConstFoldExpr::fold (expr.get_index_expr ());
+ tree array = ConstFoldExpr::fold (expr.get_array_expr ());
+ tree index = ConstFoldExpr::fold (expr.get_index_expr ());
folded = ctx->get_backend ()->array_index_expression (array, index,
expr.get_locus ());
}
+ void visit (HIR::BorrowExpr &expr) override
+ {
+ tree main_expr = ConstFoldExpr::fold (expr.get_expr ().get ());
+
+ folded
+ = ctx->get_backend ()->address_expression (main_expr, expr.get_locus ());
+ }
+
+ void visit (HIR::DereferenceExpr &expr) override
+ {
+ tree main_expr = ConstFoldExpr::fold (expr.get_expr ().get ());
+
+ TyTy::BaseType *tyty = nullptr;
+ if (!tyctx->lookup_type (expr.get_mappings ().get_hirid (), &tyty))
+ {
+ rust_fatal_error (expr.get_locus (),
+ "did not resolve type for this TupleExpr");
+ return;
+ }
+
+ tree expected_type = ConstFoldType::fold (tyty, ctx->get_backend ());
+ bool known_valid = true;
+ folded = ctx->get_backend ()->indirect_expression (expected_type, main_expr,
+ known_valid,
+ expr.get_locus ());
+ }
+
+ void visit (HIR::GroupedExpr &expr) override
+ {
+ folded = ConstFoldExpr::fold (expr.get_expr_in_parens ().get ());
+ }
+
private:
ConstFoldExpr ()
: ConstFoldBase (), folded (ctx->get_backend ()->error_expression ())
{}
- Bexpression *folded;
+ tree folded;
};
} // namespace ConstFold
diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h
index d318b9c..0c618d3 100644
--- a/gcc/rust/typecheck/rust-hir-path-probe.h
+++ b/gcc/rust/typecheck/rust-hir-path-probe.h
@@ -119,9 +119,10 @@ public:
static std::vector<PathProbeCandidate>
Probe (const TyTy::BaseType *receiver,
const HIR::PathIdentSegment &segment_name, bool probe_impls,
- bool probe_bounds, bool ignore_mandatory_trait_items)
+ bool probe_bounds, bool ignore_mandatory_trait_items,
+ DefId specific_trait_id = UNKNOWN_DEFID)
{
- PathProbeType probe (receiver, segment_name);
+ PathProbeType probe (receiver, segment_name, specific_trait_id);
if (probe_impls)
{
if (receiver->get_kind () == TyTy::TypeKind::ADT)
@@ -145,6 +146,13 @@ public:
for (auto &candidate : probed_bounds)
{
const TraitReference *trait_ref = candidate.first;
+ if (specific_trait_id != UNKNOWN_DEFID)
+ {
+ if (trait_ref->get_mappings ().get_defid ()
+ != specific_trait_id)
+ continue;
+ }
+
HIR::ImplBlock *impl = candidate.second;
probe.process_associated_trait_for_candidates (
trait_ref, impl, ignore_mandatory_trait_items);
@@ -154,6 +162,13 @@ public:
for (const TyTy::TypeBoundPredicate &predicate :
receiver->get_specified_bounds ())
{
+ const TraitReference *trait_ref = predicate.get ();
+ if (specific_trait_id != UNKNOWN_DEFID)
+ {
+ if (trait_ref->get_mappings ().get_defid () != specific_trait_id)
+ continue;
+ }
+
probe.process_predicate_for_candidates (predicate,
ignore_mandatory_trait_items);
}
@@ -221,6 +236,9 @@ public:
protected:
void process_enum_item_for_candiates (const TyTy::ADTType *adt)
{
+ if (specific_trait_id != UNKNOWN_DEFID)
+ return;
+
TyTy::VariantDef *v;
if (!adt->lookup_variant (search.as_string (), &v))
return;
@@ -385,9 +403,9 @@ protected:
protected:
PathProbeType (const TyTy::BaseType *receiver,
- const HIR::PathIdentSegment &query)
+ const HIR::PathIdentSegment &query, DefId specific_trait_id)
: TypeCheckBase (), receiver (receiver), search (query),
- current_impl (nullptr)
+ current_impl (nullptr), specific_trait_id (specific_trait_id)
{}
std::vector<std::pair<const TraitReference *, HIR::ImplBlock *>>
@@ -427,6 +445,7 @@ protected:
const HIR::PathIdentSegment &search;
std::vector<PathProbeCandidate> candidates;
HIR::ImplBlock *current_impl;
+ DefId specific_trait_id;
};
class ReportMultipleCandidateError : private TypeCheckBase
@@ -507,7 +526,8 @@ private:
PathProbeImplTrait (const TyTy::BaseType *receiver,
const HIR::PathIdentSegment &query,
const TraitReference *trait_reference)
- : PathProbeType (receiver, query), trait_reference (trait_reference)
+ : PathProbeType (receiver, query, UNKNOWN_DEFID),
+ trait_reference (trait_reference)
{}
const TraitReference *trait_reference;
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index cee6999..b2deb91 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -116,7 +116,7 @@ TraitItemReference::resolve_item (HIR::TraitItemFunc &func)
// need to get the return type from this
TyTy::FnType *resolved_fn_type = static_cast<TyTy::FnType *> (item_tyty);
auto expected_ret_tyty = resolved_fn_type->get_return_type ();
- context->push_return_type (expected_ret_tyty);
+ context->push_return_type (TypeCheckContextItem (&func), expected_ret_tyty);
auto block_expr_ty
= TypeCheckExpr::Resolve (func.get_block_expr ().get (), false);
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.h b/gcc/rust/typecheck/rust-hir-trait-resolve.h
index a32b4da..54591ce 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.h
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.h
@@ -24,6 +24,7 @@
#include "rust-tyty-visitor.h"
#include "rust-hir-type-check-type.h"
#include "rust-hir-trait-ref.h"
+#include "rust-expr.h"
namespace Rust {
namespace Resolver {
@@ -206,6 +207,31 @@ private:
// loop of trying to resolve traits as required by the types
tref->on_resolved ();
+ // does this have any lang-item attributes?
+ for (auto &attr : trait_reference->get_outer_attrs ())
+ {
+ bool is_lang_item = attr.get_path ().as_string ().compare ("lang") == 0
+ && attr.has_attr_input ()
+ && attr.get_attr_input ().get_attr_input_type ()
+ == AST::AttrInput::AttrInputType::LITERAL;
+ if (is_lang_item)
+ {
+ auto &literal
+ = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
+ const auto &lang_item_type_str
+ = literal.get_literal ().as_string ();
+ auto lang_item_type
+ = Analysis::RustLangItem::Parse (lang_item_type_str);
+ if (lang_item_type == Analysis::RustLangItem::ItemType::UNKNOWN)
+ {
+ rust_error_at (attr.get_locus (), "unknown lang item");
+ return tref;
+ }
+ mappings->insert_lang_item (
+ lang_item_type, trait_reference->get_mappings ().get_defid ());
+ }
+ }
+
return tref;
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h
index eb96fd1..52dea21 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -58,7 +58,7 @@ public:
virtual void visit (HIR::LazyBooleanExpr &) override {}
virtual void visit (HIR::TypeCastExpr &) override {}
virtual void visit (HIR::AssignmentExpr &) override {}
-
+ virtual void visit (HIR::CompoundAssignmentExpr &) override {}
virtual void visit (HIR::GroupedExpr &) override {}
virtual void visit (HIR::ArrayElemsValues &) override {}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 2a6bae9..9eef755 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -265,15 +265,29 @@ public:
bool probe_impls = !receiver_is_generic;
bool ignore_mandatory_trait_items = !receiver_is_generic;
+ auto probe_type = probe_impls ? receiver_tyty : root;
auto candidates
- = PathProbeType::Probe (root, expr.get_method_name ().get_segment (),
+ = PathProbeType::Probe (probe_type,
+ expr.get_method_name ().get_segment (),
probe_impls, probe_bounds,
ignore_mandatory_trait_items);
if (candidates.empty ())
{
- rust_error_at (expr.get_locus (),
- "failed to resolve the PathExprSegment to any item");
- return;
+ if (probe_impls)
+ {
+ candidates
+ = PathProbeType::Probe (root,
+ expr.get_method_name ().get_segment (),
+ probe_impls, probe_bounds,
+ ignore_mandatory_trait_items);
+ }
+
+ if (candidates.empty ())
+ {
+ rust_error_at (expr.get_locus (),
+ "failed to resolve the PathExprSegment to any item");
+ return;
+ }
}
std::vector<Adjustment> adjustments;
@@ -295,6 +309,10 @@ public:
return;
}
+ // Get the adjusted self
+ Adjuster adj (receiver_tyty);
+ TyTy::BaseType *adjusted_self = adj.adjust_type (adjustments);
+
// store the adjustments for code-generation to know what to do
context->insert_autoderef_mappings (expr.get_mappings ().get_hirid (),
std::move (adjustments));
@@ -401,7 +419,8 @@ public:
}
TyTy::BaseType *function_ret_tyty
- = TyTy::TypeCheckMethodCallExpr::go (lookup, expr, context);
+ = TyTy::TypeCheckMethodCallExpr::go (lookup, expr, adjusted_self,
+ context);
if (function_ret_tyty == nullptr
|| function_ret_tyty->get_kind () == TyTy::TypeKind::ERROR)
{
@@ -470,6 +489,39 @@ public:
result->clone ());
}
+ void visit (HIR::CompoundAssignmentExpr &expr) override
+ {
+ infered = new TyTy::TupleType (expr.get_mappings ().get_hirid ());
+
+ auto lhs = TypeCheckExpr::Resolve (expr.get_left_expr ().get (), false);
+ auto rhs = TypeCheckExpr::Resolve (expr.get_right_expr ().get (), false);
+
+ // we dont care about the result of the unify from a compound assignment
+ // since this is a unit-type expr
+ auto result = lhs->unify (rhs);
+ if (result->get_kind () == TyTy::TypeKind::ERROR)
+ return;
+
+ auto lang_item_type
+ = Analysis::RustLangItem::CompoundAssignmentOperatorToLangItem (
+ expr.get_expr_type ());
+ bool operator_overloaded
+ = resolve_operator_overload (lang_item_type, expr, lhs, rhs);
+ if (operator_overloaded)
+ return;
+
+ bool valid_lhs = validate_arithmetic_type (lhs, expr.get_expr_type ());
+ bool valid_rhs = validate_arithmetic_type (rhs, expr.get_expr_type ());
+ bool valid = valid_lhs && valid_rhs;
+ if (!valid)
+ {
+ rust_error_at (expr.get_locus (),
+ "cannot apply this operator to types %s and %s",
+ lhs->as_string ().c_str (), rhs->as_string ().c_str ());
+ return;
+ }
+ }
+
void visit (HIR::IdentifierExpr &expr) override
{
NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
@@ -654,7 +706,7 @@ public:
UNKNOWN_LOCAL_DEFID);
/* Capacity is the size of the string (number of chars).
- It is a constant, but for fold it to get a Bexpression. */
+ It is a constant, but for fold it to get a tree. */
std::string capacity_str
= std::to_string (expr.get_literal ()->as_string ().size ());
HIR::LiteralExpr literal_capacity (capacity_mapping, capacity_str,
@@ -667,8 +719,7 @@ public:
new TyTy::USizeType (
capacity_mapping.get_hirid ()));
- Bexpression *capacity
- = ConstFold::ConstFoldExpr::fold (&literal_capacity);
+ tree capacity = ConstFold::ConstFoldExpr::fold (&literal_capacity);
Analysis::NodeMapping array_mapping (crate_num, UNKNOWN_NODEID,
mappings->get_next_hir_id (
@@ -699,6 +750,13 @@ public:
auto lhs = TypeCheckExpr::Resolve (expr.get_lhs (), false);
auto rhs = TypeCheckExpr::Resolve (expr.get_rhs (), false);
+ auto lang_item_type
+ = Analysis::RustLangItem::OperatorToLangItem (expr.get_expr_type ());
+ bool operator_overloaded
+ = resolve_operator_overload (lang_item_type, expr, lhs, rhs);
+ if (operator_overloaded)
+ return;
+
bool valid_lhs = validate_arithmetic_type (lhs, expr.get_expr_type ());
bool valid_rhs = validate_arithmetic_type (rhs, expr.get_expr_type ());
bool valid = valid_lhs && valid_rhs;
@@ -711,8 +769,6 @@ public:
}
infered = lhs->unify (rhs);
- infered->append_reference (lhs->get_ref ());
- infered->append_reference (rhs->get_ref ());
}
void visit (HIR::ComparisonExpr &expr) override
@@ -736,17 +792,15 @@ public:
// we expect the lhs and rhs must be bools at this point
TyTy::BoolType elhs (expr.get_mappings ().get_hirid ());
lhs = elhs.unify (lhs);
- if (lhs == nullptr || lhs->get_kind () == TyTy::TypeKind::ERROR)
+ if (lhs->get_kind () == TyTy::TypeKind::ERROR)
return;
TyTy::BoolType rlhs (expr.get_mappings ().get_hirid ());
rhs = elhs.unify (rhs);
- if (lhs == nullptr || lhs->get_kind () == TyTy::TypeKind::ERROR)
+ if (lhs->get_kind () == TyTy::TypeKind::ERROR)
return;
infered = lhs->unify (rhs);
- infered->append_reference (lhs->get_ref ());
- infered->append_reference (rhs->get_ref ());
}
void visit (HIR::NegationExpr &expr) override
@@ -754,6 +808,15 @@ public:
auto negated_expr_ty
= TypeCheckExpr::Resolve (expr.get_expr ().get (), false);
+ // check for operator overload
+ auto lang_item_type = Analysis::RustLangItem::NegationOperatorToLangItem (
+ expr.get_expr_type ());
+ bool operator_overloaded
+ = resolve_operator_overload (lang_item_type, expr, negated_expr_ty,
+ nullptr);
+ if (operator_overloaded)
+ return;
+
// https://doc.rust-lang.org/reference/expressions/operator-expr.html#negation-operators
switch (expr.get_expr_type ())
{
@@ -1174,6 +1237,203 @@ public:
infered = expr_to_convert->cast (tyty_to_convert_to);
}
+protected:
+ bool
+ resolve_operator_overload (Analysis::RustLangItem::ItemType lang_item_type,
+ HIR::OperatorExpr &expr, TyTy::BaseType *lhs,
+ TyTy::BaseType *rhs)
+ {
+ // in order to probe of the correct type paths we need the root type, which
+ // strips any references
+ const TyTy::BaseType *root = lhs->get_root ();
+
+ // look up lang item for arithmetic type
+ std::vector<PathProbeCandidate> candidates;
+ std::string associated_item_name
+ = Analysis::RustLangItem::ToString (lang_item_type);
+ DefId respective_lang_item_id = UNKNOWN_DEFID;
+ bool lang_item_defined
+ = mappings->lookup_lang_item (lang_item_type, &respective_lang_item_id);
+
+ // probe for the lang-item
+ if (lang_item_defined)
+ {
+ bool receiver_is_type_param
+ = root->get_kind () == TyTy::TypeKind::PARAM;
+ bool receiver_is_dyn = root->get_kind () == TyTy::TypeKind::DYNAMIC;
+
+ bool receiver_is_generic = receiver_is_type_param || receiver_is_dyn;
+ bool probe_bounds = true;
+ bool probe_impls = !receiver_is_generic;
+ bool ignore_mandatory_trait_items = !receiver_is_generic;
+
+ candidates = PathProbeType::Probe (
+ root, HIR::PathIdentSegment (associated_item_name), probe_impls,
+ probe_bounds, ignore_mandatory_trait_items, respective_lang_item_id);
+ }
+
+ // autoderef
+ std::vector<Adjustment> adjustments;
+ PathProbeCandidate *resolved_candidate
+ = MethodResolution::Select (candidates, lhs, adjustments);
+
+ // is this the case we are recursive
+ // handle the case where we are within the impl block for this lang_item
+ // otherwise we end up with a recursive operator overload such as the i32
+ // operator overload trait
+ if (lang_item_defined && resolved_candidate != nullptr)
+ {
+ TypeCheckContextItem &fn_context = context->peek_context ();
+ if (fn_context.get_type () == TypeCheckContextItem::ItemType::IMPL_ITEM)
+ {
+ auto &impl_item = fn_context.get_impl_item ();
+ HIR::ImplBlock *parent = impl_item.first;
+ HIR::Function *fn = impl_item.second;
+
+ if (parent->has_trait_ref ()
+ && fn->get_function_name ().compare (associated_item_name) == 0)
+ {
+ TraitReference *trait_reference
+ = TraitResolver::Lookup (*parent->get_trait_ref ().get ());
+ if (!trait_reference->is_error ())
+ {
+ TyTy::BaseType *lookup = nullptr;
+ bool ok
+ = context->lookup_type (fn->get_mappings ().get_hirid (),
+ &lookup);
+ rust_assert (ok);
+ rust_assert (lookup->get_kind () == TyTy::TypeKind::FNDEF);
+
+ TyTy::FnType *fntype = static_cast<TyTy::FnType *> (lookup);
+ rust_assert (fntype->is_method ());
+
+ Adjuster adj (lhs);
+ TyTy::BaseType *adjusted = adj.adjust_type (adjustments);
+
+ bool is_lang_item_impl
+ = trait_reference->get_mappings ().get_defid ()
+ == respective_lang_item_id;
+ bool self_is_lang_item_self
+ = fntype->get_self_type ()->is_equal (*adjusted);
+ bool recursive_operator_overload
+ = is_lang_item_impl && self_is_lang_item_self;
+
+ lang_item_defined = !recursive_operator_overload;
+ }
+ }
+ }
+ }
+
+ bool have_implementation_for_lang_item = resolved_candidate != nullptr;
+ if (!lang_item_defined || !have_implementation_for_lang_item)
+ {
+ // no operator overload exists for this
+ return false;
+ }
+
+ // now its just like a method-call-expr
+ context->insert_receiver (expr.get_mappings ().get_hirid (), lhs);
+
+ // store the adjustments for code-generation to know what to do
+ context->insert_autoderef_mappings (expr.get_mappings ().get_hirid (),
+ std::move (adjustments));
+
+ TyTy::BaseType *lookup_tyty = resolved_candidate->ty;
+ NodeId resolved_node_id
+ = resolved_candidate->is_impl_candidate ()
+ ? resolved_candidate->item.impl.impl_item->get_impl_mappings ()
+ .get_nodeid ()
+ : resolved_candidate->item.trait.item_ref->get_mappings ()
+ .get_nodeid ();
+
+ rust_assert (lookup_tyty->get_kind () == TyTy::TypeKind::FNDEF);
+ TyTy::BaseType *lookup = lookup_tyty;
+ TyTy::FnType *fn = static_cast<TyTy::FnType *> (lookup);
+ rust_assert (fn->is_method ());
+
+ if (root->get_kind () == TyTy::TypeKind::ADT)
+ {
+ const TyTy::ADTType *adt = static_cast<const TyTy::ADTType *> (root);
+ if (adt->has_substitutions () && fn->needs_substitution ())
+ {
+ // consider the case where we have:
+ //
+ // struct Foo<X,Y>(X,Y);
+ //
+ // impl<T> Foo<T, i32> {
+ // fn test<X>(self, a:X) -> (T,X) { (self.0, a) }
+ // }
+ //
+ // In this case we end up with an fn type of:
+ //
+ // fn <T,X> test(self:Foo<T,i32>, a:X) -> (T,X)
+ //
+ // This means the instance or self we are calling this method for
+ // will be substituted such that we can get the inherited type
+ // arguments but then need to use the turbo fish if available or
+ // infer the remaining arguments. Luckily rust does not allow for
+ // default types GenericParams on impl blocks since these must
+ // always be at the end of the list
+
+ auto s = fn->get_self_type ()->get_root ();
+ rust_assert (s->can_eq (adt, false, false));
+ rust_assert (s->get_kind () == TyTy::TypeKind::ADT);
+ const TyTy::ADTType *self_adt
+ = static_cast<const TyTy::ADTType *> (s);
+
+ // we need to grab the Self substitutions as the inherit type
+ // parameters for this
+ if (self_adt->needs_substitution ())
+ {
+ rust_assert (adt->was_substituted ());
+
+ TyTy::SubstitutionArgumentMappings used_args_in_prev_segment
+ = GetUsedSubstArgs::From (adt);
+
+ TyTy::SubstitutionArgumentMappings inherit_type_args
+ = self_adt->solve_mappings_from_receiver_for_self (
+ used_args_in_prev_segment);
+
+ // there may or may not be inherited type arguments
+ if (!inherit_type_args.is_error ())
+ {
+ // need to apply the inherited type arguments to the
+ // function
+ lookup = fn->handle_substitions (inherit_type_args);
+ }
+ }
+ }
+ }
+
+ // type check the arguments if required
+ TyTy::FnType *type = static_cast<TyTy::FnType *> (lookup);
+ if (rhs == nullptr)
+ {
+ rust_assert (type->num_params () == 1);
+ }
+ else
+ {
+ rust_assert (type->num_params () == 2);
+ auto fnparam = type->param_at (1);
+ fnparam.second->unify (rhs); // typecheck the rhs
+ }
+
+ // get the return type
+ TyTy::BaseType *function_ret_tyty = fn->get_return_type ()->clone ();
+
+ // store the expected fntype
+ context->insert_operator_overload (expr.get_mappings ().get_hirid (), type);
+
+ // set up the resolved name on the path
+ resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (),
+ resolved_node_id);
+
+ // return the result of the function back
+ infered = function_ret_tyty;
+
+ return true;
+ }
+
private:
TypeCheckExpr (bool inside_loop)
: TypeCheckBase (), infered (nullptr), infered_array_elems (nullptr),
@@ -1249,11 +1509,11 @@ private:
/* The return value of visit(ArrayElemsValues&) and visit(ArrayElemsCopied&)
Stores the type of array elements, if `expr` is ArrayExpr. */
TyTy::BaseType *infered_array_elems;
- Bexpression *folded_array_capacity;
+ tree folded_array_capacity;
Location root_array_expr_locus;
bool inside_loop;
-};
+}; // namespace Resolver
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index 062d60b..64853f5 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -310,9 +310,10 @@ class TypeCheckImplItem : public TypeCheckBase
public:
using Rust::Resolver::TypeCheckBase::visit;
- static void Resolve (HIR::ImplItem *item, TyTy::BaseType *self)
+ static void Resolve (HIR::ImplBlock *parent, HIR::ImplItem *item,
+ TyTy::BaseType *self)
{
- TypeCheckImplItem resolver (self);
+ TypeCheckImplItem resolver (parent, self);
item->accept_vis (resolver);
}
@@ -336,7 +337,8 @@ public:
// need to get the return type from this
TyTy::FnType *resolve_fn_type = static_cast<TyTy::FnType *> (lookup);
auto expected_ret_tyty = resolve_fn_type->get_return_type ();
- context->push_return_type (expected_ret_tyty);
+ context->push_return_type (TypeCheckContextItem (parent, &function),
+ expected_ret_tyty);
auto block_expr_ty
= TypeCheckExpr::Resolve (function.get_definition ().get (), false);
@@ -346,8 +348,11 @@ public:
}
protected:
- TypeCheckImplItem (TyTy::BaseType *self) : TypeCheckBase (), self (self) {}
+ TypeCheckImplItem (HIR::ImplBlock *parent, TyTy::BaseType *self)
+ : TypeCheckBase (), parent (parent), self (self)
+ {}
+ HIR::ImplBlock *parent;
TyTy::BaseType *self;
};
@@ -357,11 +362,12 @@ class TypeCheckImplItemWithTrait : public TypeCheckImplItem
public:
static const TraitItemReference &
- Resolve (HIR::ImplItem *item, TyTy::BaseType *self,
+ Resolve (HIR::ImplBlock *parent, HIR::ImplItem *item, TyTy::BaseType *self,
TraitReference &trait_reference,
std::vector<TyTy::SubstitutionParamMapping> substitutions)
{
- TypeCheckImplItemWithTrait resolver (self, trait_reference, substitutions);
+ TypeCheckImplItemWithTrait resolver (parent, self, trait_reference,
+ substitutions);
item->accept_vis (resolver);
return resolver.resolved_trait_item;
}
@@ -514,9 +520,10 @@ public:
private:
TypeCheckImplItemWithTrait (
- TyTy::BaseType *self, TraitReference &trait_reference,
+ HIR::ImplBlock *parent, TyTy::BaseType *self,
+ TraitReference &trait_reference,
std::vector<TyTy::SubstitutionParamMapping> substitutions)
- : TypeCheckImplItem (self), trait_reference (trait_reference),
+ : TypeCheckImplItem (parent, self), trait_reference (trait_reference),
resolved_trait_item (TraitItemReference::error_node ()),
substitutions (substitutions)
{
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h
index 706f649..cc102df 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -118,11 +118,12 @@ public:
for (auto &impl_item : impl_block.get_impl_items ())
{
if (!is_trait_impl_block)
- TypeCheckImplItem::Resolve (impl_item.get (), self);
+ TypeCheckImplItem::Resolve (&impl_block, impl_item.get (), self);
else
{
auto &trait_item_ref
- = TypeCheckImplItemWithTrait::Resolve (impl_item.get (), self,
+ = TypeCheckImplItemWithTrait::Resolve (&impl_block,
+ impl_item.get (), self,
*trait_reference,
substitutions);
trait_item_refs.push_back (trait_item_ref);
@@ -210,7 +211,8 @@ public:
// need to get the return type from this
TyTy::FnType *resolved_fn_type = static_cast<TyTy::FnType *> (lookup);
auto expected_ret_tyty = resolved_fn_type->get_return_type ();
- context->push_return_type (expected_ret_tyty);
+ context->push_return_type (TypeCheckContextItem (&function),
+ expected_ret_tyty);
auto block_expr_ty
= TypeCheckExpr::Resolve (function.get_definition ().get (), false);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
index 8df43d9..fb0e047 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
@@ -424,7 +424,8 @@ public:
TyTy::FnType *resolved_fn_type = fnType;
auto expected_ret_tyty = resolved_fn_type->get_return_type ();
- context->push_return_type (expected_ret_tyty);
+ context->push_return_type (TypeCheckContextItem (&function),
+ expected_ret_tyty);
auto block_expr_ty
= TypeCheckExpr::Resolve (function.get_definition ().get (), false);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-util.h b/gcc/rust/typecheck/rust-hir-type-check-util.h
index 4595ca3..f078df6 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-util.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-util.h
@@ -51,7 +51,7 @@ public:
virtual void visit (HIR::LazyBooleanExpr &) override {}
virtual void visit (HIR::TypeCastExpr &) override {}
virtual void visit (HIR::AssignmentExpr &) override {}
-
+ virtual void visit (HIR::CompoundAssignmentExpr &) override {}
virtual void visit (HIR::GroupedExpr &) override {}
virtual void visit (HIR::ArrayElemsValues &) override {}
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index aa10f41..1add4fa 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -28,6 +28,68 @@
namespace Rust {
namespace Resolver {
+class TypeCheckContextItem
+{
+public:
+ enum ItemType
+ {
+ ITEM,
+ IMPL_ITEM,
+ TRAIT_ITEM,
+ };
+
+ TypeCheckContextItem (HIR::Function *item)
+ : type (ItemType::ITEM), item (item)
+ {}
+
+ TypeCheckContextItem (HIR::ImplBlock *impl_block, HIR::Function *item)
+ : type (ItemType::IMPL_ITEM), item (impl_block, item)
+ {}
+
+ TypeCheckContextItem (HIR::TraitItemFunc *trait_item)
+ : type (ItemType::TRAIT_ITEM), item (trait_item)
+ {}
+
+ ItemType get_type () const { return type; }
+
+ HIR::Function *get_item ()
+ {
+ rust_assert (get_type () == ItemType::ITEM);
+ return item.item;
+ }
+
+ std::pair<HIR::ImplBlock *, HIR::Function *> &get_impl_item ()
+ {
+ rust_assert (get_type () == ItemType::IMPL_ITEM);
+ return item.impl_item;
+ };
+
+ HIR::TraitItemFunc *get_trait_item ()
+ {
+ rust_assert (get_type () == ItemType::TRAIT_ITEM);
+ return item.trait_item;
+ }
+
+private:
+ union Item
+ {
+ HIR::Function *item;
+ std::pair<HIR::ImplBlock *, HIR::Function *> impl_item;
+ HIR::TraitItemFunc *trait_item;
+
+ Item (HIR::Function *item) : item (item) {}
+
+ Item (HIR::ImplBlock *impl_block, HIR::Function *item)
+ : impl_item ({impl_block, item})
+ {}
+
+ Item (HIR::TraitItemFunc *trait_item) : trait_item (trait_item) {}
+ };
+
+ ItemType type;
+ Item item;
+};
+
class TypeCheckContext
{
public:
@@ -49,7 +111,9 @@ public:
bool lookup_type_by_node_id (NodeId ref, HirId *id);
TyTy::BaseType *peek_return_type ();
- void push_return_type (TyTy::BaseType *return_type);
+ TypeCheckContextItem &peek_context ();
+ void push_return_type (TypeCheckContextItem item,
+ TyTy::BaseType *return_type);
void pop_return_type ();
void iterate (std::function<bool (HirId, TyTy::BaseType *)> cb)
@@ -232,13 +296,32 @@ public:
return true;
}
+ void insert_operator_overload (HirId id, TyTy::FnType *call_site)
+ {
+ auto it = operator_overloads.find (id);
+ rust_assert (it == operator_overloads.end ());
+
+ operator_overloads[id] = call_site;
+ }
+
+ bool lookup_operator_overload (HirId id, TyTy::FnType **call)
+ {
+ auto it = operator_overloads.find (id);
+ if (it == operator_overloads.end ())
+ return false;
+
+ *call = it->second;
+ return true;
+ }
+
private:
TypeCheckContext ();
std::map<NodeId, HirId> node_id_refs;
std::map<HirId, TyTy::BaseType *> resolved;
std::vector<std::unique_ptr<TyTy::BaseType>> builtins;
- std::vector<TyTy::BaseType *> return_type_stack;
+ std::vector<std::pair<TypeCheckContextItem, TyTy::BaseType *>>
+ return_type_stack;
std::vector<TyTy::BaseType *> loop_type_stack;
std::map<DefId, TraitReference> trait_context;
std::map<HirId, TyTy::BaseType *> receiver_context;
@@ -253,6 +336,9 @@ private:
// adjustment mappings
std::map<HirId, std::vector<Adjustment>> autoderef_mappings;
+ // operator overloads
+ std::map<HirId, TyTy::FnType *> operator_overloads;
+
// variants
std::map<HirId, HirId> variants;
};
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.cc b/gcc/rust/typecheck/rust-substitution-mapper.cc
new file mode 100644
index 0000000..a439416
--- /dev/null
+++ b/gcc/rust/typecheck/rust-substitution-mapper.cc
@@ -0,0 +1,49 @@
+// Copyright (C) 2020-2021 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-substitution-mapper.h"
+#include "rust-hir-type-check.h"
+
+namespace Rust {
+namespace Resolver {
+
+TyTy::BaseType *
+SubstMapperInternal::Resolve (TyTy::BaseType *base,
+ TyTy::SubstitutionArgumentMappings &mappings)
+{
+ SubstMapperInternal mapper (base->get_ref (), mappings);
+ base->accept_vis (mapper);
+ rust_assert (mapper.resolved != nullptr);
+
+ // insert these new implict types into the context
+ bool is_fn = mapper.resolved->get_kind () == TyTy::TypeKind::FNDEF;
+ bool is_adt = mapper.resolved->get_kind () == TyTy::TypeKind::ADT;
+ bool is_param = mapper.resolved->get_kind () == TyTy::TypeKind::PARAM;
+ if (!is_fn && !is_adt && !is_param)
+ {
+ auto context = TypeCheckContext::get ();
+ context->insert_type (
+ Analysis::NodeMapping (0, 0, mapper.resolved->get_ty_ref (), 0),
+ mapper.resolved);
+ }
+
+ return mapper.resolved;
+}
+
+} // namespace Resolver
+} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h
index 0b3ec3b..0932038 100644
--- a/gcc/rust/typecheck/rust-substitution-mapper.h
+++ b/gcc/rust/typecheck/rust-substitution-mapper.h
@@ -154,13 +154,7 @@ class SubstMapperInternal : public TyTy::TyVisitor
{
public:
static TyTy::BaseType *Resolve (TyTy::BaseType *base,
- TyTy::SubstitutionArgumentMappings &mappings)
- {
- SubstMapperInternal mapper (base->get_ref (), mappings);
- base->accept_vis (mapper);
- rust_assert (mapper.resolved != nullptr);
- return mapper.resolved;
- }
+ TyTy::SubstitutionArgumentMappings &mappings);
void visit (TyTy::FnType &type) override
{
diff --git a/gcc/rust/typecheck/rust-tyctx.cc b/gcc/rust/typecheck/rust-tyctx.cc
index 02907d7..31f8ae5 100644
--- a/gcc/rust/typecheck/rust-tyctx.cc
+++ b/gcc/rust/typecheck/rust-tyctx.cc
@@ -122,13 +122,14 @@ TypeCheckContext::lookup_type_by_node_id (NodeId ref, HirId *id)
TyTy::BaseType *
TypeCheckContext::peek_return_type ()
{
- return return_type_stack.back ();
+ return return_type_stack.back ().second;
}
void
-TypeCheckContext::push_return_type (TyTy::BaseType *return_type)
+TypeCheckContext::push_return_type (TypeCheckContextItem item,
+ TyTy::BaseType *return_type)
{
- return_type_stack.push_back (return_type);
+ return_type_stack.push_back ({std::move (item), return_type});
}
void
@@ -137,5 +138,11 @@ TypeCheckContext::pop_return_type ()
return_type_stack.pop_back ();
}
+TypeCheckContextItem &
+TypeCheckContext::peek_context ()
+{
+ return return_type_stack.back ().first;
+}
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h
index c11fd4d..3080427 100644
--- a/gcc/rust/typecheck/rust-tyty-call.h
+++ b/gcc/rust/typecheck/rust-tyty-call.h
@@ -88,9 +88,10 @@ class TypeCheckMethodCallExpr : private TyVisitor
public:
// Resolve the Method parameters and return back the return type
static BaseType *go (BaseType *ref, HIR::MethodCallExpr &call,
+ TyTy::BaseType *adjusted_self,
Resolver::TypeCheckContext *context)
{
- TypeCheckMethodCallExpr checker (call, context);
+ TypeCheckMethodCallExpr checker (call, adjusted_self, context);
ref->accept_vis (checker);
return checker.resolved;
}
@@ -125,13 +126,15 @@ public:
private:
TypeCheckMethodCallExpr (HIR::MethodCallExpr &c,
+ TyTy::BaseType *adjusted_self,
Resolver::TypeCheckContext *context)
- : resolved (nullptr), call (c), context (context),
- mappings (Analysis::Mappings::get ())
+ : resolved (nullptr), call (c), adjusted_self (adjusted_self),
+ context (context), mappings (Analysis::Mappings::get ())
{}
BaseType *resolved;
HIR::MethodCallExpr &call;
+ TyTy::BaseType *adjusted_self;
Resolver::TypeCheckContext *context;
Analysis::Mappings *mappings;
};
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 378416f..add4dbe 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -2786,6 +2786,8 @@ TypeCheckCallExpr::visit (FnPtr &type)
void
TypeCheckMethodCallExpr::visit (FnType &type)
{
+ adjusted_self->unify (type.get_self_type ());
+
// +1 for the receiver self
size_t num_args_to_call = call.num_params () + 1;
if (num_args_to_call != type.num_params ())
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index ae9ff67..915aad9 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -1324,7 +1324,7 @@ public:
params (std::move (params)), type (type), flags (flags),
identifier (identifier), id (id), abi (abi)
{
- LocalDefId local_def_id = id & DEF_ID_LOCAL_DEF_MASK;
+ LocalDefId local_def_id = id.localDefId;
rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
}
@@ -1339,7 +1339,7 @@ public:
params (params), type (type), flags (flags), identifier (identifier),
id (id), abi (abi)
{
- LocalDefId local_def_id = id & DEF_ID_LOCAL_DEF_MASK;
+ LocalDefId local_def_id = id.localDefId;
rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
}
@@ -1519,7 +1519,7 @@ public:
parameter_types (std::move (parameter_types)),
result_type (std::move (result_type)), id (id)
{
- LocalDefId local_def_id = id & DEF_ID_LOCAL_DEF_MASK;
+ LocalDefId local_def_id = id.localDefId;
rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
}
@@ -1533,7 +1533,7 @@ public:
parameter_types (std::move (parameter_types)),
result_type (std::move (result_type)), id (id)
{
- LocalDefId local_def_id = id & DEF_ID_LOCAL_DEF_MASK;
+ LocalDefId local_def_id = id.localDefId;
rust_assert (local_def_id != UNKNOWN_LOCAL_DEFID);
}
@@ -1588,13 +1588,13 @@ private:
class ArrayType : public BaseType
{
public:
- ArrayType (HirId ref, Bexpression *capacity, TyVar base,
+ ArrayType (HirId ref, tree capacity, TyVar base,
std::set<HirId> refs = std::set<HirId> ())
: BaseType (ref, ref, TypeKind::ARRAY, refs), capacity (capacity),
element_type (base)
{}
- ArrayType (HirId ref, HirId ty_ref, Bexpression *capacity, TyVar base,
+ ArrayType (HirId ref, HirId ty_ref, tree capacity, TyVar base,
std::set<HirId> refs = std::set<HirId> ())
: BaseType (ref, ty_ref, TypeKind::ARRAY, refs), capacity (capacity),
element_type (base)
@@ -1615,7 +1615,7 @@ public:
bool is_equal (const BaseType &other) const override;
- Bexpression *get_capacity () const { return capacity; }
+ tree get_capacity () const { return capacity; }
std::string capacity_string () const;
BaseType *get_element_type () const;
@@ -1628,7 +1628,7 @@ public:
}
private:
- Bexpression *capacity;
+ tree capacity;
TyVar element_type;
};
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index e965c23..9e5b509 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -63,7 +63,7 @@ NodeMapping::get_defid () const
DefId
NodeMapping::get_defid (CrateNum crate_num, LocalDefId local_defid)
{
- return ((uint64_t) crate_num << 32) | local_defid;
+ return DefId{crate_num, local_defid};
}
std::string
@@ -209,8 +209,8 @@ Mappings::insert_hir_crate (HIR::Crate *crate)
void
Mappings::insert_defid_mapping (DefId id, HIR::Item *item)
{
- CrateNum crate_num = (id & DEF_ID_CRATE_MASK) >> 32;
- LocalDefId local_def_id = id & DEF_ID_LOCAL_DEF_MASK;
+ CrateNum crate_num = id.crateNum;
+ LocalDefId local_def_id = id.localDefId;
rust_assert (lookup_defid (id) == nullptr);
rust_assert (lookup_local_defid (crate_num, local_def_id) == nullptr);
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 4fe64d45..4f8c389 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -23,13 +23,185 @@
#include "rust-location.h"
#include "rust-mapping-common.h"
#include "rust-canonical-path.h"
-
#include "rust-ast-full-decls.h"
#include "rust-hir-full-decls.h"
+#include "operator.h"
namespace Rust {
namespace Analysis {
+// https://github.com/rust-lang/rust/blob/master/library/core/src/ops/arith.rs
+class RustLangItem
+{
+public:
+ enum ItemType
+ {
+ ADD,
+ SUBTRACT,
+ MULTIPLY,
+ DIVIDE,
+ REMAINDER,
+
+ NEGATION,
+ NOT,
+
+ ADD_ASSIGN,
+ SUB_ASSIGN,
+ MUL_ASSIGN,
+ DIV_ASSIGN,
+ REM_ASSIGN,
+
+ UNKNOWN,
+ };
+
+ static ItemType Parse (const std::string &item)
+ {
+ if (item.compare ("add") == 0)
+ {
+ return ItemType::ADD;
+ }
+ else if (item.compare ("sub") == 0)
+ {
+ return ItemType::SUBTRACT;
+ }
+ else if (item.compare ("mul") == 0)
+ {
+ return ItemType::MULTIPLY;
+ }
+ else if (item.compare ("div") == 0)
+ {
+ return ItemType::DIVIDE;
+ }
+ else if (item.compare ("rem") == 0)
+ {
+ return ItemType::REMAINDER;
+ }
+ else if (item.compare ("neg") == 0)
+ {
+ return ItemType::NEGATION;
+ }
+ else if (item.compare ("not") == 0)
+ {
+ return ItemType::NOT;
+ }
+ else if (item.compare ("add_assign") == 0)
+ {
+ return ItemType::ADD_ASSIGN;
+ }
+ else if (item.compare ("sub_assign") == 0)
+ {
+ return ItemType::SUB_ASSIGN;
+ }
+ else if (item.compare ("mul_assign") == 0)
+ {
+ return ItemType::MUL_ASSIGN;
+ }
+ else if (item.compare ("div_assign") == 0)
+ {
+ return ItemType::DIV_ASSIGN;
+ }
+ else if (item.compare ("rem_assign") == 0)
+ {
+ return ItemType::REM_ASSIGN;
+ }
+
+ return ItemType::UNKNOWN;
+ }
+
+ static std::string ToString (ItemType type)
+ {
+ switch (type)
+ {
+ case ADD:
+ return "add";
+ case SUBTRACT:
+ return "sub";
+ case MULTIPLY:
+ return "mul";
+ case DIVIDE:
+ return "div";
+ case REMAINDER:
+ return "rem";
+ case NEGATION:
+ return "neg";
+ case NOT:
+ return "not";
+ case ADD_ASSIGN:
+ return "add_assign";
+ case SUB_ASSIGN:
+ return "sub_assign";
+ case MUL_ASSIGN:
+ return "mul_assign";
+ case DIV_ASSIGN:
+ return "div_assign";
+ case REM_ASSIGN:
+ return "rem_assign";
+
+ case UNKNOWN:
+ break;
+ }
+ return "<UNKNOWN>";
+ }
+
+ static ItemType OperatorToLangItem (ArithmeticOrLogicalOperator op)
+ {
+ switch (op)
+ {
+ case ArithmeticOrLogicalOperator::ADD:
+ return ItemType::ADD;
+ case ArithmeticOrLogicalOperator::SUBTRACT:
+ return ItemType::SUBTRACT;
+ case ArithmeticOrLogicalOperator::MULTIPLY:
+ return ItemType::MULTIPLY;
+ case ArithmeticOrLogicalOperator::DIVIDE:
+ return ItemType::DIVIDE;
+ case ArithmeticOrLogicalOperator::MODULUS:
+ return ItemType::REMAINDER;
+
+ default:
+ return ItemType::UNKNOWN;
+ }
+ return ItemType::UNKNOWN;
+ }
+
+ static ItemType
+ CompoundAssignmentOperatorToLangItem (ArithmeticOrLogicalOperator op)
+ {
+ switch (op)
+ {
+ case ArithmeticOrLogicalOperator::ADD:
+ return ItemType::ADD_ASSIGN;
+ case ArithmeticOrLogicalOperator::SUBTRACT:
+ return ItemType::SUB_ASSIGN;
+ case ArithmeticOrLogicalOperator::MULTIPLY:
+ return ItemType::MUL_ASSIGN;
+ case ArithmeticOrLogicalOperator::DIVIDE:
+ return ItemType::DIV_ASSIGN;
+ case ArithmeticOrLogicalOperator::MODULUS:
+ return ItemType::REM_ASSIGN;
+
+ default:
+ return ItemType::UNKNOWN;
+ }
+ return ItemType::UNKNOWN;
+ }
+
+ static ItemType NegationOperatorToLangItem (NegationOperator op)
+ {
+ switch (op)
+ {
+ case NegationOperator::NEGATE:
+ return ItemType::NEGATION;
+ case NegationOperator::NOT:
+ return ItemType::NOT;
+
+ default:
+ return ItemType::UNKNOWN;
+ }
+ return ItemType::UNKNOWN;
+ }
+};
+
class NodeMapping
{
public:
@@ -237,9 +409,9 @@ public:
const Resolver::CanonicalPath *p = nullptr;
if (lookup_canonical_path (crate, id, &p))
{
- // if we have already stored a canonical path this is ok so long as this
- // new path is equal or is smaller that the existing one but in that
- // case we ignore it.
+ // if we have already stored a canonical path this is ok so long as
+ // this new path is equal or is smaller that the existing one but in
+ // that case we ignore it.
if (p->is_equal (path))
return;
else
@@ -267,6 +439,24 @@ public:
return true;
}
+ void insert_lang_item (RustLangItem::ItemType item_type, DefId id)
+ {
+ auto it = lang_item_mappings.find (item_type);
+ rust_assert (it == lang_item_mappings.end ());
+
+ lang_item_mappings[item_type] = id;
+ }
+
+ bool lookup_lang_item (RustLangItem::ItemType item_type, DefId *id)
+ {
+ auto it = lang_item_mappings.find (item_type);
+ if (it == lang_item_mappings.end ())
+ return false;
+
+ *id = it->second;
+ return true;
+ }
+
private:
Mappings ();
@@ -304,6 +494,9 @@ private:
hirGenericParamMappings;
std::map<HirId, HIR::Trait *> hirTraitItemsToTraitMappings;
+ // this maps the lang=<item_type> to DefId mappings
+ std::map<RustLangItem::ItemType, DefId> lang_item_mappings;
+
// canonical paths
std::map<CrateNum, std::map<NodeId, const Resolver::CanonicalPath> > paths;
diff --git a/gcc/rust/util/rust-mapping-common.h b/gcc/rust/util/rust-mapping-common.h
index 1309a8d..0665779 100644
--- a/gcc/rust/util/rust-mapping-common.h
+++ b/gcc/rust/util/rust-mapping-common.h
@@ -31,17 +31,32 @@ typedef uint32_t NodeId;
typedef uint32_t HirId;
// refers to any top-level decl in HIR
typedef uint32_t LocalDefId;
-// refers to <Crate><DefId>
-typedef uint64_t DefId;
-#define DEF_ID_CRATE_MASK 0xFFFFFFFF00000000
-#define DEF_ID_LOCAL_DEF_MASK 0x00000000FFFFFFFF
+struct DefId
+{
+ CrateNum crateNum;
+ LocalDefId localDefId;
+
+ bool operator== (const DefId &other) const
+ {
+ return this->crateNum == other.crateNum
+ && this->localDefId == other.localDefId;
+ }
+
+ bool operator!= (const DefId &other) const { return !(*this == other); }
+
+ bool operator< (const DefId &other) const
+ {
+ return ((uint64_t) this->crateNum << 32 | this->localDefId)
+ < ((uint64_t) other.crateNum << 32 | other.localDefId);
+ }
+};
#define UNKNOWN_CREATENUM ((uint32_t) (0))
#define UNKNOWN_NODEID ((uint32_t) (0))
#define UNKNOWN_HIRID ((uint32_t) (0))
#define UNKNOWN_LOCAL_DEFID ((uint32_t) (0))
-#define UNKNOWN_DEFID ((uint64_t) (0))
+#define UNKNOWN_DEFID (DefId{0, 0})
} // namespace Rust
diff --git a/gcc/testsuite/rust/compile/torture/issue-808.rs b/gcc/testsuite/rust/compile/torture/issue-808.rs
new file mode 100644
index 0000000..9aa00fe
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/issue-808.rs
@@ -0,0 +1,22 @@
+pub trait Foo {
+ type Target;
+
+ fn bar(&self) -> &Self::Target;
+ // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+ // { dg-warning "unused name .Foo::bar." "" { target *-*-* } .-2 }
+}
+
+impl<T> Foo for &T {
+ type Target = T;
+
+ fn bar(&self) -> &T {
+ *self
+ }
+}
+
+pub fn main() {
+ let a: i32 = 123;
+ let b: &i32 = &a;
+
+ b.bar();
+}
diff --git a/gcc/testsuite/rust/compile/torture/traits11.rs b/gcc/testsuite/rust/compile/torture/traits11.rs
index b5fc023..41c82f0 100644
--- a/gcc/testsuite/rust/compile/torture/traits11.rs
+++ b/gcc/testsuite/rust/compile/torture/traits11.rs
@@ -1,6 +1,5 @@
trait Foo {
type A;
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
fn test(a: Self::A) -> Self::A {
a
diff --git a/gcc/testsuite/rust/compile/torture/traits4.rs b/gcc/testsuite/rust/compile/torture/traits4.rs
index 1db5f32..10d9479 100644
--- a/gcc/testsuite/rust/compile/torture/traits4.rs
+++ b/gcc/testsuite/rust/compile/torture/traits4.rs
@@ -1,8 +1,6 @@
trait Foo {
type A;
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
type B;
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
fn new(a: Self::A, b: Self::B) -> Self;
// { dg-warning "unused name .a." "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/torture/traits5.rs b/gcc/testsuite/rust/compile/torture/traits5.rs
index 87c0283..4a396a0 100644
--- a/gcc/testsuite/rust/compile/torture/traits5.rs
+++ b/gcc/testsuite/rust/compile/torture/traits5.rs
@@ -1,8 +1,6 @@
trait Foo {
type A;
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
type B;
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
fn new(a: Self::A, b: Self::B) -> Self;
// { dg-warning "unused name .a." "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/compile/torture/traits6.rs b/gcc/testsuite/rust/compile/torture/traits6.rs
index 5aae2e3..a69c6fd 100644
--- a/gcc/testsuite/rust/compile/torture/traits6.rs
+++ b/gcc/testsuite/rust/compile/torture/traits6.rs
@@ -1,6 +1,5 @@
trait Foo {
type A;
- // { dg-warning "unused name .Foo::A." "" { target *-*-* } .-1 }
fn baz(a: Self::A) -> Self::A;
// { dg-warning "unused name .a." "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_1.rs b/gcc/testsuite/rust/execute/torture/operator_overload_1.rs
new file mode 100644
index 0000000..997ab04
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_1.rs
@@ -0,0 +1,39 @@
+/* { dg-output "3\n" } */
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[lang = "add"]
+pub trait Add<Rhs = Self> {
+ type Output;
+
+ fn add(self, rhs: Rhs) -> Self::Output;
+ // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+ // { dg-warning "unused name .rhs." "" { target *-*-* } .-2 }
+ // { dg-warning "unused name .Add::add." "" { target *-*-* } .-3 }
+}
+
+impl Add for i32 {
+ type Output = i32;
+
+ fn add(self, other: i32) -> i32 {
+ let res = self + other;
+
+ unsafe {
+ let a = "%i\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c, res);
+ }
+
+ res
+ }
+}
+
+fn main() -> i32 {
+ let a;
+ a = 1 + 2;
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_2.rs b/gcc/testsuite/rust/execute/torture/operator_overload_2.rs
new file mode 100644
index 0000000..8d6a073
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_2.rs
@@ -0,0 +1,41 @@
+/* { dg-output "3\n" } */
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[lang = "add"]
+pub trait Add<Rhs = Self> {
+ type Output;
+
+ fn add(self, rhs: Rhs) -> Self::Output;
+ // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+ // { dg-warning "unused name .rhs." "" { target *-*-* } .-2 }
+ // { dg-warning "unused name .Add::add." "" { target *-*-* } .-3 }
+}
+
+struct Foo(i32);
+
+impl Add for Foo {
+ type Output = Foo;
+
+ fn add(self, other: Foo) -> Foo {
+ let res = Foo(self.0 + other.0);
+
+ unsafe {
+ let a = "%i\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c, res.0);
+ }
+
+ res
+ }
+}
+
+fn main() -> i32 {
+ let a;
+ a = Foo(1) + Foo(2);
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_3.rs b/gcc/testsuite/rust/execute/torture/operator_overload_3.rs
new file mode 100644
index 0000000..50ff799
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_3.rs
@@ -0,0 +1,58 @@
+/* { dg-output "3\n3\n" } */
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[lang = "add"]
+pub trait Add<Rhs = Self> {
+ type Output;
+
+ fn add(self, rhs: Rhs) -> Self::Output;
+ // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+ // { dg-warning "unused name .rhs." "" { target *-*-* } .-2 }
+ // { dg-warning "unused name .Add::add." "" { target *-*-* } .-3 }
+}
+
+impl Add for i32 {
+ type Output = i32;
+
+ fn add(self, other: i32) -> i32 {
+ let res = self + other;
+
+ unsafe {
+ let a = "%i\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c, res);
+ }
+
+ res
+ }
+}
+
+struct Foo(i32);
+impl Add for Foo {
+ type Output = Foo;
+
+ fn add(self, other: Foo) -> Foo {
+ let res = Foo(self.0 + other.0);
+
+ unsafe {
+ let a = "%i\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c, res.0);
+ }
+
+ res
+ }
+}
+
+fn main() -> i32 {
+ let a;
+ a = Foo(1) + Foo(2);
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_4.rs b/gcc/testsuite/rust/execute/torture/operator_overload_4.rs
new file mode 100644
index 0000000..5ca5c7a
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_4.rs
@@ -0,0 +1,35 @@
+/* { dg-output "neg\n" } */
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[lang = "neg"]
+pub trait Neg {
+ type Output;
+
+ fn neg(self) -> Self::Output;
+ // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+ // { dg-warning "unused name .Neg::neg." "" { target *-*-* } .-2 }
+}
+
+impl Neg for i32 {
+ type Output = i32;
+
+ fn neg(self) -> i32 {
+ unsafe {
+ let a = "neg\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c);
+ }
+ -self
+ }
+}
+
+fn main() -> i32 {
+ let a: i32 = 1;
+ let _b = -a;
+
+ 0
+}
diff --git a/gcc/testsuite/rust/execute/torture/operator_overload_5.rs b/gcc/testsuite/rust/execute/torture/operator_overload_5.rs
new file mode 100644
index 0000000..5aac3ad
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/operator_overload_5.rs
@@ -0,0 +1,35 @@
+/* { dg-output "not\n" } */
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+#[lang = "not"]
+pub trait Not {
+ type Output;
+
+ fn not(self) -> Self::Output;
+ // { dg-warning "unused name .self." "" { target *-*-* } .-1 }
+ // { dg-warning "unused name .Not::not." "" { target *-*-* } .-2 }
+}
+
+impl Not for i32 {
+ type Output = i32;
+
+ fn not(self) -> i32 {
+ unsafe {
+ let a = "not\n\0";
+ let b = a as *const str;
+ let c = b as *const i8;
+
+ printf(c);
+ }
+ !self
+ }
+}
+
+fn main() -> i32 {
+ let a: i32 = 1;
+ let _b = !a;
+
+ 0
+}