aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-ast-full-test.cc47
-rw-r--r--gcc/rust/ast/rust-item.h11
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc11
-rw-r--r--gcc/rust/parse/rust-parse.h4
-rw-r--r--gcc/testsuite/rust/compile/extern_mod2.rs14
-rw-r--r--gcc/testsuite/rust/compile/torture/extern_mod1.rs6
-rw-r--r--gcc/testsuite/rust/compile/torture/extern_mod2.rs16
-rw-r--r--gcc/testsuite/rust/compile/torture/extern_mod4.rs17
-rw-r--r--gcc/testsuite/rust/compile/torture/modules/mod.rs3
-rw-r--r--gcc/testsuite/rust/compile/torture/modules/valid_path.rs (renamed from gcc/testsuite/rust/compile/modules/valid_path.rs)0
10 files changed, 103 insertions, 26 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc
index 2477d74..9b11498 100644
--- a/gcc/rust/ast/rust-ast-full-test.cc
+++ b/gcc/rust/ast/rust-ast-full-test.cc
@@ -24,6 +24,8 @@ along with GCC; see the file COPYING3. If not see
#include "rust-diagnostics.h"
#include "rust-ast-visitor.h"
#include "rust-session-manager.h"
+#include "rust-lex.h"
+#include "rust-parse.h"
#include "operator.h"
/* Compilation unit used for various AST-related functions that would make
@@ -4023,14 +4025,15 @@ filename_from_path_attribute (std::vector<Attribute> &outer_attrs)
return path_attr.get_attr_input ().as_string ();
}
-std::string
-Module::get_filename ()
+void
+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 path_string;
+ return;
// This corresponds to the path of the file 'including' the module. So the
// file that contains the 'mod <file>;' directive
@@ -4076,8 +4079,42 @@ Module::get_filename ()
rust_error_at (locus, "no candidate found for module %s",
module_name.c_str ());
- return file_mod_found ? expected_file_path
- : current_directory_name + expected_dir_path;
+ module_file = file_mod_found ? expected_file_path
+ : current_directory_name + expected_dir_path;
+}
+
+void
+Module::load_items ()
+{
+ process_file_path ();
+
+ // We will already have errored out appropriately in the process_file_path ()
+ // method
+ if (module_file.empty ())
+ return;
+
+ RAIIFile file_wrap (module_file.c_str ());
+ Linemap *linemap = Session::get_instance ().linemap;
+
+ if (file_wrap.get_raw () == nullptr)
+ {
+ rust_error_at (Location (), "cannot open module file %s: %m",
+ module_file.c_str ());
+ return;
+ }
+
+ rust_debug ("Attempting to parse file %s", module_file.c_str ());
+
+ Lexer lex (module_file.c_str (), std::move (file_wrap), linemap);
+ Parser<Lexer> parser (std::move (lex));
+
+ auto parsed_items = parser.parse_items ();
+
+ for (const auto &error : parser.get_errors ())
+ error.emit_error ();
+
+ items = std::move (parsed_items);
+ kind = ModuleKind::LOADED;
}
void
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 881a888..7a34144 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -982,6 +982,10 @@ private:
// bool has_items;
std::vector<std::unique_ptr<Item>> items;
+ // Filename the module refers to. Empty string on LOADED modules or if an
+ // error occured when dealing with UNLOADED modules
+ std::string module_file;
+
void clone_items (const std::vector<std::unique_ptr<Item>> &other_items)
{
items.reserve (other_items.size ());
@@ -1051,8 +1055,11 @@ public:
return *this;
}
- // Search for the filename associated with an external module
- std::string get_filename ();
+ // Search for the filename associated with an external module, storing it in
+ // module_file
+ void process_file_path ();
+ // Load the items contained in an external module
+ void load_items ();
void accept_vis (ASTVisitor &vis) override;
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 8134f7e..e531b21 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -1896,11 +1896,14 @@ public:
return;
}
}
- else
+
+ // Parse the module's items if they haven't been expanded and the file
+ // should be parsed (i.e isn't hidden behind an untrue or impossible cfg
+ // directive)
+ if (!module.is_marked_for_strip ()
+ && module.get_kind () == AST::Module::ModuleKind::UNLOADED)
{
- std::string mod_file = module.get_filename ();
- if (!mod_file.empty ())
- rust_debug ("Module filename found: %s", mod_file.c_str ());
+ module.load_items ();
}
// strip items if required
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 86e0d2a..45f00f5 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -595,7 +595,6 @@ private:
bool done_end_of_file ();
void add_error (Error error) { error_table.push_back (std::move (error)); }
- std::vector<Error> &get_errors () { return error_table; }
public:
// Construct parser with specified "managed" token source.
@@ -615,6 +614,9 @@ public:
// Returns whether any parsing errors have occurred.
bool has_errors () const { return !error_table.empty (); }
+ // Get a reference to the list of errors encountered
+ std::vector<Error> &get_errors () { return error_table; }
+
private:
// The token source (usually lexer) associated with the parser.
ManagedTokenSource lexer;
diff --git a/gcc/testsuite/rust/compile/extern_mod2.rs b/gcc/testsuite/rust/compile/extern_mod2.rs
deleted file mode 100644
index 67c8a13..0000000
--- a/gcc/testsuite/rust/compile/extern_mod2.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-#[path = "modules/valid_path.rs"]
-mod not_a_valid_path;
-
-#[path] // { dg-error "path attributes must contain a filename" }
-mod error; // { dg-error "no candidate found for module error" }
-
-// This is "valid", and should only error out when parsing
-// the file
-// FIXME: Add a dg-error directive on the `mod another_error` line once module expansion
-// is added
-#[path = "not_a_valid_file.rs"]
-mod another_error;
-
-fn main() {}
diff --git a/gcc/testsuite/rust/compile/torture/extern_mod1.rs b/gcc/testsuite/rust/compile/torture/extern_mod1.rs
new file mode 100644
index 0000000..4b576e0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/extern_mod1.rs
@@ -0,0 +1,6 @@
+// { dg-additional-options "-w" }
+mod modules;
+
+fn main() {
+ let twelve = modules::return_12();
+}
diff --git a/gcc/testsuite/rust/compile/torture/extern_mod2.rs b/gcc/testsuite/rust/compile/torture/extern_mod2.rs
new file mode 100644
index 0000000..f3379e3
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/extern_mod2.rs
@@ -0,0 +1,16 @@
+// { dg-additional-options "-w" }
+
+#[path = "modules/valid_path.rs"]
+mod not_a_valid_path;
+
+// #[path]
+// FIXME: This is wrong
+// mod error;
+
+// 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;
+
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/torture/extern_mod4.rs b/gcc/testsuite/rust/compile/torture/extern_mod4.rs
new file mode 100644
index 0000000..80d8497
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/extern_mod4.rs
@@ -0,0 +1,17 @@
+// { dg-additional-options "-w" }
+// { dg-output "12" }
+mod modules;
+
+extern "C" {
+ fn printf(s: *const i8, ...);
+}
+
+fn main() {
+ unsafe {
+ let fmt_s = "%d\n\0";
+ let fmt_p = fmt_s as *const str;
+ let fmt_i8 = fmt_p as *const i8;
+
+ printf(fmt_i8, modules::return_12());
+ }
+}
diff --git a/gcc/testsuite/rust/compile/torture/modules/mod.rs b/gcc/testsuite/rust/compile/torture/modules/mod.rs
new file mode 100644
index 0000000..3d65176
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/modules/mod.rs
@@ -0,0 +1,3 @@
+pub fn return_12() -> i32 {
+ 12
+}
diff --git a/gcc/testsuite/rust/compile/modules/valid_path.rs b/gcc/testsuite/rust/compile/torture/modules/valid_path.rs
index 6a1519c..6a1519c 100644
--- a/gcc/testsuite/rust/compile/modules/valid_path.rs
+++ b/gcc/testsuite/rust/compile/torture/modules/valid_path.rs