aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/Make-lang.in1
-rw-r--r--gcc/rust/backend/rust-compile-base.cc81
-rw-r--r--gcc/rust/backend/rust-compile-base.h4
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc17
-rw-r--r--gcc/rust/backend/rust-compile-expr.h8
-rw-r--r--gcc/rust/backend/rust-compile-fnparam.h33
-rw-r--r--gcc/rust/backend/rust-compile-var-decl.h16
-rw-r--r--gcc/rust/backend/rust-compile.cc3
-rw-r--r--gcc/rust/rust-backend.h121
-rw-r--r--gcc/rust/rust-gcc.cc249
-rw-r--r--gcc/rust/typecheck/rust-hir-address-taken.cc65
-rw-r--r--gcc/rust/typecheck/rust-hir-address-taken.h159
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h12
13 files changed, 118 insertions, 651 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 2d74595..660ed23 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -88,7 +88,6 @@ GRS_OBJS = \
rust/rust-hir-trait-resolve.o \
rust/rust-hir-type-check-type.o \
rust/rust-hir-type-check-struct.o \
- rust/rust-hir-address-taken.o \
rust/rust-hir-type-check-pattern.o \
rust/rust-autoderef.o \
rust/rust-substitution-mapper.o \
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index 82a38e7..81598c4 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -17,6 +17,7 @@
// <http://www.gnu.org/licenses/>.
#include "rust-compile-base.h"
+#include "fold-const.h"
#include "stringpool.h"
namespace Rust {
@@ -88,5 +89,85 @@ HIRCompileBase::setup_abi_options (tree fndecl, ABI abi)
}
}
+// ported from gcc/c/c-typecheck.c
+//
+// Mark EXP saying that we need to be able to take the
+// address of it; it should not be allocated in a register.
+// Returns true if successful. ARRAY_REF_P is true if this
+// is for ARRAY_REF construction - in that case we don't want
+// to look through VIEW_CONVERT_EXPR from VECTOR_TYPE to ARRAY_TYPE,
+// it is fine to use ARRAY_REFs for vector subscripts on vector
+// register variables.
+bool
+HIRCompileBase::mark_addressable (tree exp, Location locus)
+{
+ tree x = exp;
+
+ while (1)
+ switch (TREE_CODE (x))
+ {
+ case VIEW_CONVERT_EXPR:
+ if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
+ && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))))
+ return true;
+ x = TREE_OPERAND (x, 0);
+ break;
+
+ case COMPONENT_REF:
+ // TODO
+ // if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1)))
+ // {
+ // error ("cannot take address of bit-field %qD", TREE_OPERAND (x,
+ // 1)); return false;
+ // }
+
+ /* FALLTHRU */
+ case ADDR_EXPR:
+ case ARRAY_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ x = TREE_OPERAND (x, 0);
+ break;
+
+ case COMPOUND_LITERAL_EXPR:
+ TREE_ADDRESSABLE (x) = 1;
+ TREE_ADDRESSABLE (COMPOUND_LITERAL_EXPR_DECL (x)) = 1;
+ return true;
+
+ case CONSTRUCTOR:
+ TREE_ADDRESSABLE (x) = 1;
+ return true;
+
+ case VAR_DECL:
+ case CONST_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ // (we don't have a concept of a "register" declaration)
+ // fallthrough */
+
+ /* FALLTHRU */
+ case FUNCTION_DECL:
+ TREE_ADDRESSABLE (x) = 1;
+
+ /* FALLTHRU */
+ default:
+ return true;
+ }
+
+ return false;
+}
+
+tree
+HIRCompileBase::address_expression (tree expr, Location location)
+{
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ if (!mark_addressable (expr, location))
+ return error_mark_node;
+
+ return build_fold_addr_expr_loc (location.gcc_location (), expr);
+}
+
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index f318e81..ec75356 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -77,6 +77,10 @@ protected:
const HIR::FunctionQualifiers &qualifiers, const AST::AttrVec &attrs);
static void setup_abi_options (tree fndecl, ABI abi);
+
+ static tree address_expression (tree, Location);
+
+ static bool mark_addressable (tree, Location);
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index d49a6dc..f65e1fd 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -124,6 +124,13 @@ CompileExpr::visit (HIR::NegationExpr &expr)
}
void
+CompileExpr::visit (HIR::BorrowExpr &expr)
+{
+ tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
+ translated = address_expression (main_expr, expr.get_locus ());
+}
+
+void
CompileExpr::visit (HIR::DereferenceExpr &expr)
{
TyTy::BaseType *tyty = nullptr;
@@ -973,7 +980,7 @@ CompileExpr::compile_string_literal (const HIR::LiteralExpr &expr,
auto base = ctx->get_backend ()->string_constant_expression (
literal_value.as_string ());
- return ctx->get_backend ()->address_expression (base, expr.get_locus ());
+ return address_expression (base, expr.get_locus ());
}
tree
@@ -1006,8 +1013,7 @@ CompileExpr::compile_byte_string_literal (const HIR::LiteralExpr &expr,
vals,
expr.get_locus ());
- return ctx->get_backend ()->address_expression (constructed,
- expr.get_locus ());
+ return address_expression (constructed, expr.get_locus ());
}
tree
@@ -1190,7 +1196,7 @@ HIRCompileBase::resolve_adjustements (
case Resolver::Adjustment::AdjustmentType::IMM_REF:
case Resolver::Adjustment::AdjustmentType::MUT_REF:
- e = ctx->get_backend ()->address_expression (e, locus);
+ e = address_expression (e, locus);
break;
case Resolver::Adjustment::AdjustmentType::DEREF_REF:
@@ -1235,8 +1241,7 @@ HIRCompileBase::resolve_deref_adjustment (Resolver::Adjustment &adjustment,
!= Resolver::Adjustment::AdjustmentType::ERROR;
if (needs_borrow)
{
- adjusted_argument
- = ctx->get_backend ()->address_expression (expression, locus);
+ adjusted_argument = address_expression (expression, locus);
}
// make the call
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 43eff72..592d280 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -797,13 +797,7 @@ public:
ctx->add_statement (goto_label);
}
- void visit (HIR::BorrowExpr &expr) override
- {
- tree main_expr = CompileExpr::Compile (expr.get_expr ().get (), ctx);
-
- translated
- = ctx->get_backend ()->address_expression (main_expr, expr.get_locus ());
- }
+ void visit (HIR::BorrowExpr &expr) override;
void visit (HIR::DereferenceExpr &expr) override;
diff --git a/gcc/rust/backend/rust-compile-fnparam.h b/gcc/rust/backend/rust-compile-fnparam.h
index d8b63b6..4ca26ec 100644
--- a/gcc/rust/backend/rust-compile-fnparam.h
+++ b/gcc/rust/backend/rust-compile-fnparam.h
@@ -20,7 +20,6 @@
#define RUST_COMPILE_FNPARAM
#include "rust-compile-base.h"
-#include "rust-hir-address-taken.h"
namespace Rust {
namespace Compile {
@@ -34,7 +33,7 @@ public:
HIR::FunctionParam *param, tree decl_type,
Location locus)
{
- CompileFnParam compiler (ctx, fndecl, decl_type, locus, *param);
+ CompileFnParam compiler (ctx, fndecl, decl_type, locus);
param->get_param_name ()->accept_vis (compiler);
return compiler.compiled_param;
}
@@ -44,39 +43,30 @@ public:
if (!pattern.is_mut ())
decl_type = ctx->get_backend ()->immutable_type (decl_type);
- bool address_taken = false;
- address_taken_context->lookup_addess_taken (
- param.get_mappings ().get_hirid (), &address_taken);
-
- compiled_param = ctx->get_backend ()->parameter_variable (
- fndecl, pattern.get_identifier (), decl_type, address_taken, locus);
+ compiled_param
+ = ctx->get_backend ()->parameter_variable (fndecl,
+ pattern.get_identifier (),
+ decl_type, locus);
}
void visit (HIR::WildcardPattern &pattern) override
{
decl_type = ctx->get_backend ()->immutable_type (decl_type);
- bool address_taken = false;
compiled_param
- = ctx->get_backend ()->parameter_variable (fndecl, "_", decl_type,
- address_taken, locus);
+ = ctx->get_backend ()->parameter_variable (fndecl, "_", decl_type, locus);
}
private:
- CompileFnParam (Context *ctx, tree fndecl, tree decl_type, Location locus,
- const HIR::FunctionParam &param)
+ CompileFnParam (Context *ctx, tree fndecl, tree decl_type, Location locus)
: HIRCompileBase (ctx), fndecl (fndecl), decl_type (decl_type),
- locus (locus), param (param),
- compiled_param (ctx->get_backend ()->error_variable ()),
- address_taken_context (Resolver::AddressTakenContext::get ())
+ locus (locus), compiled_param (ctx->get_backend ()->error_variable ())
{}
tree fndecl;
tree decl_type;
Location locus;
- const HIR::FunctionParam &param;
Bvariable *compiled_param;
- const Resolver::AddressTakenContext *address_taken_context;
};
class CompileSelfParam : public HIRCompileBase
@@ -91,13 +81,8 @@ public:
if (is_immutable)
decl_type = ctx->get_backend ()->immutable_type (decl_type);
- const auto &address_taken_context = Resolver::AddressTakenContext::get ();
- bool address_taken = false;
- address_taken_context->lookup_addess_taken (
- self.get_mappings ().get_hirid (), &address_taken);
-
return ctx->get_backend ()->parameter_variable (fndecl, "self", decl_type,
- address_taken, locus);
+ locus);
}
};
diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h
index 48becfa..7bc37eb 100644
--- a/gcc/rust/backend/rust-compile-var-decl.h
+++ b/gcc/rust/backend/rust-compile-var-decl.h
@@ -20,7 +20,6 @@
#define RUST_COMPILE_VAR_DECL
#include "rust-compile-base.h"
-#include "rust-hir-address-taken.h"
namespace Rust {
namespace Compile {
@@ -47,9 +46,6 @@ public:
&resolved_type);
rust_assert (ok);
- address_taken_context->lookup_addess_taken (
- stmt.get_mappings ().get_hirid (), &address_taken);
-
translated_type = TyTyResolveCompile::compile (ctx, resolved_type);
stmt.get_pattern ()->accept_vis (*this);
}
@@ -62,33 +58,29 @@ public:
compiled_variable
= ctx->get_backend ()->local_variable (fndecl, pattern.get_identifier (),
translated_type, NULL /*decl_var*/,
- address_taken, locus);
+ locus);
}
void visit (HIR::WildcardPattern &pattern) override
{
translated_type = ctx->get_backend ()->immutable_type (translated_type);
+
compiled_variable
= ctx->get_backend ()->local_variable (fndecl, "_", translated_type,
- NULL /*decl_var*/, address_taken,
- locus);
+ NULL /*decl_var*/, locus);
}
private:
CompileVarDecl (Context *ctx, tree fndecl)
: HIRCompileBase (ctx), fndecl (fndecl),
translated_type (ctx->get_backend ()->error_type ()),
- compiled_variable (ctx->get_backend ()->error_variable ()),
- address_taken (false),
- address_taken_context (Resolver::AddressTakenContext::get ())
+ compiled_variable (ctx->get_backend ()->error_variable ())
{}
tree fndecl;
tree translated_type;
Location locus;
Bvariable *compiled_variable;
- bool address_taken;
- const Resolver::AddressTakenContext *address_taken_context;
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index b0447af..2299ddb 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -387,8 +387,7 @@ HIRCompileBase::coerce_to_dyn_object (tree compiled_ref,
rust_assert (ok);
resulting_dyn_object_ref
- = ctx->get_backend ()->address_expression (resulting_dyn_object_ref,
- locus);
+ = address_expression (resulting_dyn_object_ref, locus);
}
return resulting_dyn_object_ref;
}
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index 2a7691c..f7a1ac6 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -255,9 +255,6 @@ public:
// get the address of the code for a function.
virtual tree function_code_expression (tree, Location) = 0;
- // Create an expression that takes the address of an expression.
- virtual tree address_expression (tree, Location) = 0;
-
// Return an expression for the field at INDEX in BSTRUCT.
virtual tree struct_field_expression (tree bstruct, size_t index, Location)
= 0;
@@ -461,15 +458,14 @@ public:
// the frontend will call init_statement to set the initial value.
virtual Bvariable *local_variable (tree function, const std::string &name,
tree type, Bvariable *decl_var,
- bool is_address_taken, Location location)
+ 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 (tree function, const std::string &name,
- tree type, bool is_address_taken,
- Location location)
+ tree type, Location location)
= 0;
// Create a static chain parameter. This is the closure parameter.
@@ -494,119 +490,6 @@ public:
Location location, tree *pstatement)
= 0;
- // Create an implicit variable that is compiler-defined. This is
- // used when generating GC data and roots, when storing the values
- // of a slice constructor, and for the zero value of types. This returns a
- // Bvariable because it corresponds to an initialized variable in C.
- //
- // NAME is the name to use for the initialized variable this will create.
- //
- // ASM_NAME is encoded assembler-friendly version of the name, or the
- // empty string if no encoding is needed.
- //
- // TYPE is the type of the implicit variable.
- //
- // IS_HIDDEN will be true if the descriptor should only be visible
- // within the current object.
- //
- // IS_CONSTANT is true if the implicit variable should be treated like it is
- // immutable. For slice initializers, if the values must be copied to the
- // heap, the variable IS_CONSTANT.
- //
- // IS_COMMON is true if the implicit variable should
- // be treated as a common variable (multiple definitions with
- // different sizes permitted in different object files, all merged
- // into the largest definition at link time); this will be true for
- // 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, 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.
- // This must be called even if there is no initializer, i.e., INIT is NULL.
- // The NAME, TYPE, IS_HIDDEN, IS_CONSTANT, and IS_COMMON parameters are
- // the same ones passed to implicit_variable. INIT will be a composite
- // literal of type TYPE. It will not contain any function calls or anything
- // else that can not be put into a read-only data section.
- // It may contain the address of variables created by implicit_variable.
- //
- // 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,
- tree type, bool is_hidden,
- bool is_constant, bool is_common,
- tree init)
- = 0;
-
- // Create a reference to a named implicit variable defined in some
- // other package. This will be a variable created by a call to
- // implicit_variable with the same NAME, ASM_NAME and TYPE and with
- // IS_COMMON passed as false. This corresponds to an extern global
- // variable in C.
- virtual Bvariable *implicit_variable_reference (const std::string &name,
- const std::string &asm_name,
- tree type)
- = 0;
-
- // Create a named immutable initialized data structure. This is
- // used for type descriptors, map descriptors, and function
- // descriptors. This returns a Bvariable because it corresponds to
- // an initialized const variable in C.
- //
- // NAME is the name to use for the initialized global variable which
- // this call will create.
- //
- // ASM_NAME is the encoded, assembler-friendly version of NAME, or
- // the empty string if no encoding is needed.
- //
- // IS_HIDDEN will be true if the descriptor should only be visible
- // within the current object.
- //
- // IS_COMMON is true if NAME may be defined by several packages, and
- // the linker should merge all such definitions. If IS_COMMON is
- // false, NAME should be defined in only one file. In general
- // IS_COMMON will be true for the type descriptor of an unnamed type
- // or a builtin type. IS_HIDDEN and IS_COMMON will never both be
- // true.
- //
- // TYPE will be a struct type; the type of the returned expression
- // must be a pointer to this struct type.
- //
- // We must create the named structure before we know its
- // initializer, because the initializer may refer to its own
- // address. After calling this the frontend will call
- // immutable_struct_set_init.
- virtual Bvariable *
- immutable_struct (const std::string &name, const std::string &asm_name,
- bool is_hidden, bool is_common, tree type, Location)
- = 0;
-
- // Set the initial value of a variable created by immutable_struct.
- // The NAME, IS_HIDDEN, IS_COMMON, TYPE, and location parameters are
- // the same ones passed to immutable_struct. INITIALIZER will be a
- // composite literal of type TYPE. It will not contain any function
- // calls or anything else that can not be put into a read-only data
- // section. It may contain the address of variables created by
- // immutable_struct.
- virtual void immutable_struct_set_init (Bvariable *, const std::string &name,
- bool is_hidden, bool is_common,
- tree type, Location, tree initializer)
- = 0;
-
- // Create a reference to a named immutable initialized data
- // structure defined in some other package. This will be a
- // structure created by a call to immutable_struct with the same
- // NAME, ASM_NAME and TYPE and with IS_COMMON passed as false. This
- // corresponds to an extern const global variable in C.
- virtual Bvariable *immutable_struct_reference (const std::string &name,
- const std::string &asm_name,
- tree type, Location)
- = 0;
-
// Labels.
// Create a new label. NAME will be empty if this is a label
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 62c9d80..86a4106 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -231,8 +231,6 @@ public:
tree function_code_expression (tree, Location);
- tree address_expression (tree, Location);
-
tree struct_field_expression (tree, size_t, Location);
tree compound_expression (tree, tree, Location);
@@ -312,35 +310,16 @@ public:
void global_variable_set_init (Bvariable *, tree);
- Bvariable *local_variable (tree, const std::string &, tree, Bvariable *, bool,
+ Bvariable *local_variable (tree, const std::string &, tree, Bvariable *,
Location);
- Bvariable *parameter_variable (tree, const std::string &, tree, bool,
- Location);
+ Bvariable *parameter_variable (tree, const std::string &, tree, Location);
Bvariable *static_chain_variable (tree, const std::string &, tree, Location);
Bvariable *temporary_variable (tree, tree, tree, tree, bool, Location,
tree *);
- Bvariable *implicit_variable (const std::string &, const std::string &, tree,
- bool, bool, bool, int64_t);
-
- void implicit_variable_set_init (Bvariable *, const std::string &, tree, bool,
- bool, bool, tree);
-
- Bvariable *implicit_variable_reference (const std::string &,
- const std::string &, tree);
-
- Bvariable *immutable_struct (const std::string &, const std::string &, bool,
- bool, tree, Location);
-
- void immutable_struct_set_init (Bvariable *, const std::string &, bool, bool,
- tree, Location, tree);
-
- Bvariable *immutable_struct_reference (const std::string &,
- const std::string &, tree, Location);
-
// Labels.
tree label (tree, const std::string &name, Location);
@@ -1338,17 +1317,6 @@ Gcc_backend::function_code_expression (tree func, Location location)
return ret;
}
-// Get the address of an expression.
-
-tree
-Gcc_backend::address_expression (tree expr, Location location)
-{
- if (expr == error_mark_node)
- return this->error_expression ();
-
- return build_fold_addr_expr_loc (location.gcc_location (), expr);
-}
-
// Return an expression for the field at INDEX in BSTRUCT.
tree
@@ -2495,7 +2463,7 @@ Gcc_backend::global_variable_set_init (Bvariable *var, tree expr_tree)
Bvariable *
Gcc_backend::local_variable (tree function, const std::string &name,
tree type_tree, Bvariable *decl_var,
- bool is_address_taken, Location location)
+ Location location)
{
if (type_tree == error_mark_node)
return this->error_variable ();
@@ -2503,8 +2471,7 @@ Gcc_backend::local_variable (tree function, const std::string &name,
get_identifier_from_string (name), type_tree);
DECL_CONTEXT (decl) = function;
TREE_USED (decl) = 1;
- if (is_address_taken)
- TREE_ADDRESSABLE (decl) = 1;
+
if (decl_var != NULL)
{
DECL_HAS_VALUE_EXPR_P (decl) = 1;
@@ -2518,8 +2485,7 @@ Gcc_backend::local_variable (tree function, const std::string &name,
Bvariable *
Gcc_backend::parameter_variable (tree function, const std::string &name,
- tree type_tree, bool is_address_taken,
- Location location)
+ tree type_tree, Location location)
{
if (type_tree == error_mark_node)
return this->error_variable ();
@@ -2528,8 +2494,6 @@ Gcc_backend::parameter_variable (tree function, const std::string &name,
DECL_CONTEXT (decl) = function;
DECL_ARG_TYPE (decl) = type_tree;
TREE_USED (decl) = 1;
- if (is_address_taken)
- TREE_ADDRESSABLE (decl) = 1;
rust_preserve_from_gc (decl);
return new Bvariable (decl);
}
@@ -2633,209 +2597,6 @@ Gcc_backend::temporary_variable (tree fndecl, tree bind_tree, tree type_tree,
return new Bvariable (var);
}
-// Create an implicit variable that is compiler-defined. This is used when
-// generating GC root variables and storing the values of a slice initializer.
-
-Bvariable *
-Gcc_backend::implicit_variable (const std::string &name,
- const std::string &asm_name, tree type_tree,
- bool is_hidden, bool is_constant,
- bool is_common, int64_t alignment)
-{
- if (type_tree == error_mark_node)
- return this->error_variable ();
-
- tree decl = build_decl (BUILTINS_LOCATION, VAR_DECL,
- get_identifier_from_string (name), type_tree);
- DECL_EXTERNAL (decl) = 0;
- TREE_PUBLIC (decl) = !is_hidden;
- TREE_STATIC (decl) = 1;
- TREE_USED (decl) = 1;
- DECL_ARTIFICIAL (decl) = 1;
- if (is_common)
- {
- DECL_COMMON (decl) = 1;
-
- // When the initializer for one implicit_variable refers to another,
- // it needs to know the visibility of the referenced struct so that
- // compute_reloc_for_constant will return the right value. On many
- // systems calling make_decl_one_only will mark the decl as weak,
- // which will change the return value of compute_reloc_for_constant.
- // We can't reliably call make_decl_one_only yet, because we don't
- // yet know the initializer. This issue doesn't arise in C because
- // Rust initializers, unlike C initializers, can be indirectly
- // recursive. To ensure that compute_reloc_for_constant computes
- // the right value if some other initializer refers to this one, we
- // mark this symbol as weak here. We undo that below in
- // immutable_struct_set_init before calling mark_decl_one_only.
- DECL_WEAK (decl) = 1;
- }
- if (is_constant)
- {
- TREE_READONLY (decl) = 1;
- TREE_CONSTANT (decl) = 1;
- }
- if (alignment != 0)
- {
- SET_DECL_ALIGN (decl, alignment * BITS_PER_UNIT);
- DECL_USER_ALIGN (decl) = 1;
- }
- if (!asm_name.empty ())
- SET_DECL_ASSEMBLER_NAME (decl, get_identifier_from_string (asm_name));
-
- rust_preserve_from_gc (decl);
- return new Bvariable (decl);
-}
-
-// Set the initalizer for a variable created by implicit_variable.
-// This is where we finish compiling the variable.
-
-void
-Gcc_backend::implicit_variable_set_init (Bvariable *var, const std::string &,
- tree, bool, bool, bool is_common,
- tree init_tree)
-{
- tree decl = var->get_decl ();
- if (decl == error_mark_node || init_tree == error_mark_node)
- return;
-
- DECL_INITIAL (decl) = init_tree;
-
- // Now that DECL_INITIAL is set, we can't call make_decl_one_only.
- // See the comment where DECL_WEAK is set in implicit_variable.
- if (is_common)
- {
- DECL_WEAK (decl) = 0;
- make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
- }
-
- resolve_unique_section (decl, 2, 1);
-
- rest_of_decl_compilation (decl, 1, 0);
-}
-
-// Return a reference to an implicit variable defined in another package.
-
-Bvariable *
-Gcc_backend::implicit_variable_reference (const std::string &name,
- const std::string &asm_name,
- tree type_tree)
-{
- if (type_tree == error_mark_node)
- return this->error_variable ();
-
- tree decl = build_decl (BUILTINS_LOCATION, VAR_DECL,
- get_identifier_from_string (name), type_tree);
- DECL_EXTERNAL (decl) = 1;
- TREE_PUBLIC (decl) = 1;
- TREE_STATIC (decl) = 0;
- DECL_ARTIFICIAL (decl) = 1;
- if (!asm_name.empty ())
- SET_DECL_ASSEMBLER_NAME (decl, get_identifier_from_string (asm_name));
- rust_preserve_from_gc (decl);
- return new Bvariable (decl);
-}
-
-// Create a named immutable initialized data structure.
-
-Bvariable *
-Gcc_backend::immutable_struct (const std::string &name,
- const std::string &asm_name, bool is_hidden,
- bool is_common, tree type_tree,
- Location location)
-{
- if (type_tree == error_mark_node)
- return this->error_variable ();
- gcc_assert (TREE_CODE (type_tree) == RECORD_TYPE);
- tree decl = build_decl (location.gcc_location (), VAR_DECL,
- get_identifier_from_string (name),
- build_qualified_type (type_tree, TYPE_QUAL_CONST));
- TREE_STATIC (decl) = 1;
- TREE_USED (decl) = 1;
- TREE_READONLY (decl) = 1;
- TREE_CONSTANT (decl) = 1;
- DECL_ARTIFICIAL (decl) = 1;
- if (!is_hidden)
- TREE_PUBLIC (decl) = 1;
- if (!asm_name.empty ())
- SET_DECL_ASSEMBLER_NAME (decl, get_identifier_from_string (asm_name));
-
- // When the initializer for one immutable_struct refers to another,
- // it needs to know the visibility of the referenced struct so that
- // compute_reloc_for_constant will return the right value. On many
- // systems calling make_decl_one_only will mark the decl as weak,
- // which will change the return value of compute_reloc_for_constant.
- // We can't reliably call make_decl_one_only yet, because we don't
- // yet know the initializer. This issue doesn't arise in C because
- // Rust initializers, unlike C initializers, can be indirectly
- // recursive. To ensure that compute_reloc_for_constant computes
- // the right value if some other initializer refers to this one, we
- // mark this symbol as weak here. We undo that below in
- // immutable_struct_set_init before calling mark_decl_one_only.
- if (is_common)
- DECL_WEAK (decl) = 1;
-
- // We don't call rest_of_decl_compilation until we have the
- // initializer.
-
- rust_preserve_from_gc (decl);
- return new Bvariable (decl);
-}
-
-// Set the initializer for a variable created by immutable_struct.
-// This is where we finish compiling the variable.
-
-void
-Gcc_backend::immutable_struct_set_init (Bvariable *var, const std::string &,
- bool, bool is_common, tree, Location,
- tree init_tree)
-{
- tree decl = var->get_decl ();
- if (decl == error_mark_node || init_tree == error_mark_node)
- return;
-
- DECL_INITIAL (decl) = init_tree;
-
- // Now that DECL_INITIAL is set, we can't call make_decl_one_only.
- // See the comment where DECL_WEAK is set in immutable_struct.
- if (is_common)
- {
- DECL_WEAK (decl) = 0;
- make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
- }
-
- // These variables are often unneeded in the final program, so put
- // them in their own section so that linker GC can discard them.
- resolve_unique_section (decl, compute_reloc_for_constant (init_tree), 1);
-
- rest_of_decl_compilation (decl, 1, 0);
-}
-
-// Return a reference to an immutable initialized data structure
-// defined in another package.
-
-Bvariable *
-Gcc_backend::immutable_struct_reference (const std::string &name,
- const std::string &asm_name,
- tree type_tree, Location location)
-{
- if (type_tree == error_mark_node)
- return this->error_variable ();
- gcc_assert (TREE_CODE (type_tree) == RECORD_TYPE);
- tree decl = build_decl (location.gcc_location (), VAR_DECL,
- get_identifier_from_string (name),
- build_qualified_type (type_tree, TYPE_QUAL_CONST));
- TREE_READONLY (decl) = 1;
- TREE_CONSTANT (decl) = 1;
- DECL_ARTIFICIAL (decl) = 1;
- TREE_PUBLIC (decl) = 1;
- DECL_EXTERNAL (decl) = 1;
- if (!asm_name.empty ())
- SET_DECL_ASSEMBLER_NAME (decl, get_identifier_from_string (asm_name));
- rust_preserve_from_gc (decl);
- return new Bvariable (decl);
-}
-
// Make a label.
tree
diff --git a/gcc/rust/typecheck/rust-hir-address-taken.cc b/gcc/rust/typecheck/rust-hir-address-taken.cc
deleted file mode 100644
index 8fcbb37..0000000
--- a/gcc/rust/typecheck/rust-hir-address-taken.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (C) 2020-2022 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-hir-address-taken.h"
-#include "rust-hir-full.h"
-
-namespace Rust {
-namespace Resolver {
-
-AddressTakenContext *
-AddressTakenContext::get ()
-{
- static AddressTakenContext *instance;
- if (instance == nullptr)
- instance = new AddressTakenContext ();
-
- return instance;
-}
-
-AddressTakenContext::~AddressTakenContext () {}
-
-bool
-AddressTakenContext::lookup_addess_taken (HirId id, bool *address_taken) const
-{
- const auto &it = ctx.find (id);
- if (it == ctx.end ())
- return false;
-
- *address_taken = it->second;
- return true;
-}
-
-void
-AddressTakenContext::insert_address_taken (HirId id, bool address_taken)
-{
- const auto &it = ctx.find (id);
- if (it != ctx.end ())
- {
- // assert that we never change a true result to a negative
- if (it->second == true)
- {
- rust_assert (address_taken != false);
- }
- }
-
- ctx[id] = address_taken;
-}
-
-} // namespace Resolver
-} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-address-taken.h b/gcc/rust/typecheck/rust-hir-address-taken.h
deleted file mode 100644
index 32a1445..0000000
--- a/gcc/rust/typecheck/rust-hir-address-taken.h
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (C) 2020-2022 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/>.
-
-#ifndef RUST_HIR_ADDRESS_TAKEN
-#define RUST_HIR_ADDRESS_TAKEN
-
-#include "rust-hir-type-check-base.h"
-
-namespace Rust {
-namespace Resolver {
-
-class AddressTakenContext
-{
-public:
- static AddressTakenContext *get ();
-
- ~AddressTakenContext ();
-
- bool lookup_addess_taken (HirId id, bool *address_taken) const;
-
- void insert_address_taken (HirId id, bool address_taken);
-
-private:
- std::map<HirId, bool> ctx;
-};
-
-class AddressTakenResolver : public TypeCheckBase
-{
- using Rust::Resolver::TypeCheckBase::visit;
-
-public:
- static void SetAddressTaken (HIR::Expr &expr)
- {
- AddressTakenResolver resolver;
- expr.accept_vis (resolver);
- }
-
- void visit (HIR::IdentifierExpr &expr) override
- {
- NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
- NodeId ref_node_id = UNKNOWN_NODEID;
- if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
- {
- // these ref_node_ids will resolve to a pattern declaration but we are
- // interested in the definition that this refers to get the parent id
- Definition def;
- if (!resolver->lookup_definition (ref_node_id, &def))
- {
- rust_error_at (expr.get_locus (),
- "unknown reference for resolved name");
- return;
- }
- ref_node_id = def.parent;
- }
-
- if (ref_node_id == UNKNOWN_NODEID)
- return;
-
- // node back to HIR
- HirId ref = UNKNOWN_HIRID;
- bool reverse_lookup
- = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
- ref_node_id, &ref);
- rust_assert (reverse_lookup);
- context->insert_address_taken (ref, true);
- }
-
- void visit (HIR::PathInExpression &expr) override
- {
- NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
- NodeId ref_node_id = UNKNOWN_NODEID;
- if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
- {
- // these ref_node_ids will resolve to a pattern declaration but we are
- // interested in the definition that this refers to get the parent id
- Definition def;
- if (!resolver->lookup_definition (ref_node_id, &def))
- {
- rust_error_at (expr.get_locus (),
- "unknown reference for resolved name");
- return;
- }
- ref_node_id = def.parent;
- }
-
- if (ref_node_id == UNKNOWN_NODEID)
- return;
-
- // node back to HIR
- HirId ref = UNKNOWN_HIRID;
- bool reverse_lookup
- = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
- ref_node_id, &ref);
- rust_assert (reverse_lookup);
- context->insert_address_taken (ref, true);
- }
-
- void visit (HIR::QualifiedPathInExpression &expr) override
- {
- NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
- NodeId ref_node_id = UNKNOWN_NODEID;
- if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
- {
- // these ref_node_ids will resolve to a pattern declaration but we are
- // interested in the definition that this refers to get the parent id
- Definition def;
- if (!resolver->lookup_definition (ref_node_id, &def))
- {
- rust_error_at (expr.get_locus (),
- "unknown reference for resolved name");
- return;
- }
- ref_node_id = def.parent;
- }
-
- if (ref_node_id == UNKNOWN_NODEID)
- return;
-
- // node back to HIR
- HirId ref = UNKNOWN_HIRID;
- bool reverse_lookup
- = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
- ref_node_id, &ref);
- rust_assert (reverse_lookup);
- context->insert_address_taken (ref, true);
- }
-
- void visit (HIR::DereferenceExpr &expr) override
- {
- expr.get_expr ()->accept_vis (*this);
- }
-
-private:
- AddressTakenResolver ()
- : TypeCheckBase (), context (AddressTakenContext::get ())
- {}
-
- AddressTakenContext *context;
-};
-
-} // namespace Resolver
-} // namespace Rust
-
-#endif // RUST_HIR_ADDRESS_TAKEN
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 150eb1a..2cb4461 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -30,7 +30,6 @@
#include "rust-hir-trait-resolve.h"
#include "rust-hir-type-bounds.h"
#include "rust-hir-dot-operator.h"
-#include "rust-hir-address-taken.h"
#include "rust-hir-type-check-pattern.h"
namespace Rust {
@@ -260,10 +259,6 @@ public:
Adjuster adj (receiver_tyty);
TyTy::BaseType *adjusted_self = adj.adjust_type (candidate.adjustments);
- // mark the required tree addressable
- if (Adjuster::needs_address (candidate.adjustments))
- AddressTakenResolver::SetAddressTaken (*expr.get_receiver ().get ());
-
// store the adjustments for code-generation to know what to do
context->insert_autoderef_mappings (expr.get_mappings ().get_hirid (),
std::move (candidate.adjustments));
@@ -1177,9 +1172,6 @@ public:
infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (),
TyTy::TyVar (resolved_base->get_ref ()),
expr.get_mut ());
-
- // mark the borrowed as address_taken
- AddressTakenResolver::SetAddressTaken (*expr.get_expr ().get ());
}
void visit (HIR::DereferenceExpr &expr) override
@@ -1350,10 +1342,6 @@ protected:
}
}
- // mark the required tree addressable
- if (Adjuster::needs_address (candidate.adjustments))
- AddressTakenResolver::SetAddressTaken (*expr.get_expr ().get ());
-
// store the adjustments for code-generation to know what to do
context->insert_autoderef_mappings (expr.get_mappings ().get_hirid (),
std::move (candidate.adjustments));