diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/Make-lang.in | 1 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-base.cc | 81 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-base.h | 4 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.cc | 17 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.h | 8 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-fnparam.h | 33 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-var-decl.h | 16 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 3 | ||||
-rw-r--r-- | gcc/rust/rust-backend.h | 121 | ||||
-rw-r--r-- | gcc/rust/rust-gcc.cc | 249 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-address-taken.cc | 65 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-address-taken.h | 159 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 12 |
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 ¶m) + 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 ¶m; 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)); |