diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/ast/rust-ast-full-test.cc | 28 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-extern.h | 8 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-intrinsic.cc | 3 | ||||
-rw-r--r-- | gcc/rust/rust-abi.h | 35 | ||||
-rw-r--r-- | gcc/rust/rust-backend.h | 47 | ||||
-rw-r--r-- | gcc/rust/rust-gcc.cc | 51 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-base.h | 1 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-implitem.h | 16 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-stmt.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-toplevel.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check.cc | 12 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 39 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/extern_mod2.rs | 19 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/extern_mod4.rs (renamed from gcc/testsuite/rust/compile/torture/extern_mod4.rs) | 4 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/modules/mod.rs | 3 |
15 files changed, 197 insertions, 73 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc index 9b11498..b1572e1 100644 --- a/gcc/rust/ast/rust-ast-full-test.cc +++ b/gcc/rust/ast/rust-ast-full-test.cc @@ -4010,7 +4010,15 @@ filename_from_path_attribute (std::vector<Attribute> &outer_attrs) return ""; } - auto path = path_attr.get_attr_input ().as_string (); + auto path_value = path_attr.get_attr_input ().as_string (); + + // At this point, the 'path' is of the following format: '= "<file.rs>"' + // We need to remove the equal sign and only keep the actual filename. + // In order to do this, we can simply go through the string until we find + // a character that is not an equal sign or whitespace + auto filename_begin = path_value.find_first_not_of ("=\t "); + + auto path = path_value.substr (filename_begin); // On windows, the path might mix '/' and '\' separators. Replace the // UNIX-like separators by MSDOS separators to make sure the path will resolve @@ -4022,7 +4030,7 @@ filename_from_path_attribute (std::vector<Attribute> &outer_attrs) path.replace ('/', '\\'); #endif /* HAVE_DOS_BASED_FILE_SYSTEM */ - return path_attr.get_attr_input ().as_string (); + return path; } void @@ -4031,10 +4039,6 @@ Module::process_file_path () rust_assert (kind == Module::ModuleKind::UNLOADED); rust_assert (module_file.empty ()); - auto path_string = filename_from_path_attribute (get_outer_attrs ()); - if (!path_string.empty ()) - return; - // This corresponds to the path of the file 'including' the module. So the // file that contains the 'mod <file>;' directive std::string including_fname (outer_filename); @@ -4053,6 +4057,13 @@ Module::process_file_path () current_directory_name = including_fname.substr (0, dir_slash_pos) + file_separator; + auto path_string = filename_from_path_attribute (get_outer_attrs ()); + if (!path_string.empty ()) + { + module_file = current_directory_name + path_string; + return; + } + // FIXME: We also have to search for // <directory>/<including_fname>/<module_name>.rs In rustc, this is done via // the concept of `DirOwnernship`, which is based on whether or not the @@ -4079,6 +4090,9 @@ Module::process_file_path () rust_error_at (locus, "no candidate found for module %s", module_name.c_str ()); + if (no_candidates_found || multiple_candidates_found) + return; + module_file = file_mod_found ? expected_file_path : current_directory_name + expected_dir_path; } @@ -4098,7 +4112,7 @@ Module::load_items () if (file_wrap.get_raw () == nullptr) { - rust_error_at (Location (), "cannot open module file %s: %m", + rust_error_at (get_locus (), "cannot open module file %s: %m", module_file.c_str ()); return; } diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h index d78a566..f0aacee 100644 --- a/gcc/rust/backend/rust-compile-extern.h +++ b/gcc/rust/backend/rust-compile-extern.h @@ -119,7 +119,7 @@ public: fntype->override_context (); } - if (fntype->get_abi () == TyTy::FnType::ABI::INTRINSIC) + if (fntype->get_abi () == ABI::INTRINSIC) { Intrinsics compile (ctx); Bfunction *fndecl = compile.compile (fntype); @@ -127,19 +127,21 @@ public: return; } - rust_assert (fntype->get_abi () == TyTy::FnType::ABI::C); ::Btype *compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype); + compiled_fn_type + = ctx->get_backend ()->specify_abi_attribute (compiled_fn_type, + fntype->get_abi ()); const unsigned int flags = Backend::function_is_declaration | Backend::function_is_visible; std::string ir_symbol_name = function.get_item_name (); - // FIXME this assumes C ABI std::string asm_name = function.get_item_name (); Bfunction *fndecl = ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name, asm_name, flags, function.get_locus ()); + ctx->insert_function_decl (fntype->get_ty_ref (), fndecl, fntype); } diff --git a/gcc/rust/backend/rust-compile-intrinsic.cc b/gcc/rust/backend/rust-compile-intrinsic.cc index 4068a7a..66d36e3 100644 --- a/gcc/rust/backend/rust-compile-intrinsic.cc +++ b/gcc/rust/backend/rust-compile-intrinsic.cc @@ -24,8 +24,9 @@ Intrinsics::Intrinsics (Context *ctx) : ctx (ctx) {} Bfunction * Intrinsics::compile (TyTy::FnType *fntype) { - rust_assert (fntype->get_abi () == TyTy::FnType::ABI::INTRINSIC); + rust_assert (fntype->get_abi () == ABI::INTRINSIC); + // https://github.com/rust-lang/rust/blob/master/library/core/src/intrinsics.rs // https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/intrinsic.rs // https://github.com/Rust-GCC/gccrs/issues/658 diff --git a/gcc/rust/rust-abi.h b/gcc/rust/rust-abi.h new file mode 100644 index 0000000..bd30432 --- /dev/null +++ b/gcc/rust/rust-abi.h @@ -0,0 +1,35 @@ +// 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_ABI_OPTIONS_H +#define RUST_ABI_OPTIONS_H + +namespace Rust { + +enum ABI +{ + UNKNOWN, + RUST, + INTRINSIC, + C, + CDECL, + STDCALL, + FASTCALL, +}; + +} // namespace Rust + +#endif // RUST_ABI_OPTIONS_H diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h index 105b2ea..b6f18f8 100644 --- a/gcc/rust/rust-backend.h +++ b/gcc/rust/rust-backend.h @@ -25,7 +25,9 @@ #include "rust-location.h" #include "rust-linemap.h" +#include "rust-diagnostics.h" #include "operator.h" +#include "rust-abi.h" extern bool saw_errors (void); @@ -98,6 +100,49 @@ public: virtual std::string const_size_val_to_string (Bexpression *) = 0; virtual bool const_values_equal (Bexpression *, Bexpression *) = 0; + static Rust::ABI get_abi_from_string (const std::string &abi, Location locus) + { + if (abi.compare ("rust") == 0) + return Rust::ABI::C; + else if (abi.compare ("rust-intrinsic") == 0) + return Rust::ABI::INTRINSIC; + else if (abi.compare ("C") == 0) + return Rust::ABI::C; + else if (abi.compare ("cdecl") == 0) + return Rust::ABI::CDECL; + else if (abi.compare ("stdcall") == 0) + return Rust::ABI::STDCALL; + else if (abi.compare ("fastcall") == 0) + return Rust::ABI::FASTCALL; + + rust_error_at (locus, "unknown abi specified"); + + return Rust::ABI::UNKNOWN; + } + + static std::string get_string_from_abi (Rust::ABI abi) + { + switch (abi) + { + case Rust::ABI::RUST: + return "rust"; + case Rust::ABI::INTRINSIC: + return "rust-intrinsic"; + case Rust::ABI::C: + return "C"; + case Rust::ABI::CDECL: + return "cdecl"; + case Rust::ABI::STDCALL: + return "stdcall"; + case Rust::ABI::FASTCALL: + return "fastcall"; + + case Rust::ABI::UNKNOWN: + return "unknown"; + } + return "unknown"; + } + // Types. // Produce an error type. Actually the backend could probably just @@ -818,6 +863,8 @@ public: Location) = 0; + virtual Btype *specify_abi_attribute (Btype *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: diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc index 4c1dda8..0b17865 100644 --- a/gcc/rust/rust-gcc.cc +++ b/gcc/rust/rust-gcc.cc @@ -44,6 +44,7 @@ #include "realmpfr.h" #include "builtins.h" #include "print-tree.h" +#include "attribs.h" #include "rust-location.h" #include "rust-linemap.h" @@ -251,6 +252,10 @@ public: 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 *, @@ -925,6 +930,52 @@ Gcc_backend::immutable_type (Btype *base) return this->make_type (constified); } +// ABI + +Btype * +Gcc_backend::specify_abi_attribute (Btype *type, Rust::ABI abi) +{ + std::string abi_string; + switch (abi) + { + case Rust::ABI::UNKNOWN: + return error_type (); + + case Rust::ABI::RUST: + case Rust::ABI::INTRINSIC: + case Rust::ABI::C: + case Rust::ABI::CDECL: + abi_string = "cdecl"; + break; + + case Rust::ABI::STDCALL: + abi_string = "stdcall"; + break; + case Rust::ABI::FASTCALL: + abi_string = "fastcall"; + break; + } + + return insert_type_attribute (type, abi_string); +} + +Btype * +Gcc_backend::insert_type_attribute (Btype *type, const std::string &attrname) +{ + tree ident = get_identifier (attrname.c_str ()); + + tree attribs = NULL_TREE; + tree old_attrs = TYPE_ATTRIBUTES (type->get_tree ()); + 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); +} + // Make a function type. Btype * diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h index 26fb506..0b4daea 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-base.h +++ b/gcc/rust/typecheck/rust-hir-type-check-base.h @@ -24,6 +24,7 @@ #include "rust-name-resolver.h" #include "rust-hir-visitor.h" #include "rust-hir-map.h" +#include "rust-backend.h" namespace Rust { namespace Resolver { diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h index b1eb2e3..d3977c3 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h +++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h @@ -118,8 +118,7 @@ public: auto fnType = new TyTy::FnType ( function.get_mappings ().get_hirid (), function.get_mappings ().get_defid (), function.get_item_name (), flags, - TyTy::FnType::get_abi_from_string (parent.get_abi (), - parent.get_locus ()), + ::Backend::get_abi_from_string (parent.get_abi (), parent.get_locus ()), std::move (params), ret_type, std::move (substitutions)); context->insert_type (function.get_mappings (), fnType); } @@ -238,14 +237,11 @@ public: context->insert_type (param.get_mappings (), param_tyty); } - auto fnType - = new TyTy::FnType (function.get_mappings ().get_hirid (), - function.get_mappings ().get_defid (), - function.get_function_name (), - function.is_method () ? FNTYPE_IS_METHOD_FLAG - : FNTYPE_DEFAULT_FLAGS, - TyTy::FnType::ABI::RUST, std::move (params), ret_type, - std::move (substitutions)); + auto fnType = new TyTy::FnType ( + function.get_mappings ().get_hirid (), + function.get_mappings ().get_defid (), function.get_function_name (), + function.is_method () ? FNTYPE_IS_METHOD_FLAG : FNTYPE_DEFAULT_FLAGS, + ABI::RUST, std::move (params), ret_type, std::move (substitutions)); context->insert_type (function.get_mappings (), fnType); } diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h index 54280e8..5f4721b 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h +++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h @@ -333,7 +333,7 @@ public: = new TyTy::FnType (function.get_mappings ().get_hirid (), function.get_mappings ().get_defid (), function.get_function_name (), FNTYPE_DEFAULT_FLAGS, - TyTy::FnType::ABI::RUST, std::move (params), ret_type, + ABI::RUST, std::move (params), ret_type, std::move (substitutions)); context->insert_type (function.get_mappings (), fnType); diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h index 6ec17a9..9fac813 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h +++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h @@ -291,7 +291,7 @@ public: = new TyTy::FnType (function.get_mappings ().get_hirid (), function.get_mappings ().get_defid (), function.get_function_name (), FNTYPE_DEFAULT_FLAGS, - TyTy::FnType::ABI::RUST, std::move (params), ret_type, + ABI::RUST, std::move (params), ret_type, std::move (substitutions)); context->insert_type (function.get_mappings (), fnType); } diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc index bee2748..f960f77 100644 --- a/gcc/rust/typecheck/rust-hir-type-check.cc +++ b/gcc/rust/typecheck/rust-hir-type-check.cc @@ -546,11 +546,13 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const context->insert_type (param.get_mappings (), param_tyty); } - auto resolved = new TyTy::FnType ( - fn.get_mappings ().get_hirid (), fn.get_mappings ().get_defid (), - function.get_function_name (), - function.is_method () ? FNTYPE_IS_METHOD_FLAG : FNTYPE_DEFAULT_FLAGS, - TyTy::FnType::ABI::RUST, std::move (params), ret_type, substitutions); + auto resolved + = new TyTy::FnType (fn.get_mappings ().get_hirid (), + fn.get_mappings ().get_defid (), + function.get_function_name (), + function.is_method () ? FNTYPE_IS_METHOD_FLAG + : FNTYPE_DEFAULT_FLAGS, + ABI::RUST, std::move (params), ret_type, substitutions); context->insert_type (fn.get_mappings (), resolved); return resolved; diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 867dc37..d3d4afd 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -23,6 +23,7 @@ #include "rust-hir-map.h" #include "rust-hir-full.h" #include "rust-diagnostics.h" +#include "rust-abi.h" namespace Rust { namespace Resolver { @@ -1080,44 +1081,6 @@ public: #define FNTYPE_IS_EXTERN_FLAG 0x02 #define FNTYPE_IS_VARADIC_FLAG 0X04 - enum ABI - { - UNKNOWN, - RUST, - INTRINSIC, - C, - }; - - static ABI get_abi_from_string (const std::string &abi, Location locus) - { - if (abi.compare ("rust") == 0) - return ABI::C; - else if (abi.compare ("rust-intrinsic") == 0) - return ABI::INTRINSIC; - else if (abi.compare ("C") == 0) - return ABI::C; - - rust_error_at (locus, "unknown abi specified"); - return ABI::UNKNOWN; - } - - static std::string get_string_from_abi (ABI abi) - { - switch (abi) - { - case ABI::RUST: - return "rust"; - case ABI::INTRINSIC: - return "rust-intrinsic"; - case ABI::C: - return "C"; - - case ABI::UNKNOWN: - return "unknown"; - } - return "unknown"; - } - FnType (HirId ref, DefId id, std::string identifier, uint8_t flags, ABI abi, std::vector<std::pair<HIR::Pattern *, BaseType *>> params, BaseType *type, std::vector<SubstitutionParamMapping> subst_refs, diff --git a/gcc/testsuite/rust/compile/torture/extern_mod2.rs b/gcc/testsuite/rust/compile/torture/extern_mod2.rs index f3379e3..4984d5d 100644 --- a/gcc/testsuite/rust/compile/torture/extern_mod2.rs +++ b/gcc/testsuite/rust/compile/torture/extern_mod2.rs @@ -3,14 +3,21 @@ #[path = "modules/valid_path.rs"] mod not_a_valid_path; -// #[path] -// FIXME: This is wrong -// mod error; +#[path ="modules/valid_path.rs"] +mod path_without_extra_equal; + +#[path= "modules/valid_path.rs"] +mod no_leading_equal; + +#[path = "modules/valid_path.rs"] +mod extra_spaces; + +#[path] // { dg-error "path attributes must contain a filename" } +mod error; // { dg-error "no candidate found" } // This is "valid", and should only error out when parsing // the file -// FIXME: Fix path attribute expanding -// #[path = "not_a_valid_file.rs"] -// mod another_error; +#[path = "not_a_valid_file.rs"] +mod another_error; // { dg-error "No such file or directory" } fn main() {} diff --git a/gcc/testsuite/rust/compile/torture/extern_mod4.rs b/gcc/testsuite/rust/execute/torture/extern_mod4.rs index 80d8497..99b6fb5 100644 --- a/gcc/testsuite/rust/compile/torture/extern_mod4.rs +++ b/gcc/testsuite/rust/execute/torture/extern_mod4.rs @@ -6,7 +6,7 @@ extern "C" { fn printf(s: *const i8, ...); } -fn main() { +fn main() -> i32 { unsafe { let fmt_s = "%d\n\0"; let fmt_p = fmt_s as *const str; @@ -14,4 +14,6 @@ fn main() { printf(fmt_i8, modules::return_12()); } + + return 0; } diff --git a/gcc/testsuite/rust/execute/torture/modules/mod.rs b/gcc/testsuite/rust/execute/torture/modules/mod.rs new file mode 100644 index 0000000..9020aaf --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/modules/mod.rs @@ -0,0 +1,3 @@ +fn return_12() -> i32 { + 12 +} |