aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-09-09 13:22:33 +0000
committerGitHub <noreply@github.com>2021-09-09 13:22:33 +0000
commit38f2795947ab8d8080bab81c5e2ccdd24981cbcc (patch)
treeccb4cab2678bc6e7ac50b4549e48481bc35da9ae
parent4c4241b4c8da925b7f39e0045d3d36fbf71551f8 (diff)
parent8cd6306905b31a0fb92f95e8472c6a8e26a17b04 (diff)
downloadgcc-38f2795947ab8d8080bab81c5e2ccdd24981cbcc.zip
gcc-38f2795947ab8d8080bab81c5e2ccdd24981cbcc.tar.gz
gcc-38f2795947ab8d8080bab81c5e2ccdd24981cbcc.tar.bz2
Merge #639
639: External module expansion r=philberty a=CohenArthur Needs #638 This PR parses the file associated with an external module and allows their compilation. The two test cases are not currently passing, and the locations will be inexact (the filename for the parsed module will just show as random characters), so the PR is still a draft. Co-authored-by: CohenArthur <arthur.cohen@epita.fr>
-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