aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-ast-full-test.cc28
-rw-r--r--gcc/rust/backend/rust-compile-extern.h8
-rw-r--r--gcc/rust/backend/rust-compile-intrinsic.cc3
-rw-r--r--gcc/rust/rust-abi.h35
-rw-r--r--gcc/rust/rust-backend.h47
-rw-r--r--gcc/rust/rust-gcc.cc51
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.h1
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.h16
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-stmt.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc12
-rw-r--r--gcc/rust/typecheck/rust-tyty.h39
-rw-r--r--gcc/testsuite/rust/compile/torture/extern_mod2.rs19
-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.rs3
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
+}