diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-09-09 13:22:33 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-09 13:22:33 +0000 |
commit | 38f2795947ab8d8080bab81c5e2ccdd24981cbcc (patch) | |
tree | ccb4cab2678bc6e7ac50b4549e48481bc35da9ae | |
parent | 4c4241b4c8da925b7f39e0045d3d36fbf71551f8 (diff) | |
parent | 8cd6306905b31a0fb92f95e8472c6a8e26a17b04 (diff) | |
download | gcc-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.cc | 47 | ||||
-rw-r--r-- | gcc/rust/ast/rust-item.h | 11 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.cc | 11 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse.h | 4 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/extern_mod2.rs | 14 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/extern_mod1.rs | 6 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/extern_mod2.rs | 16 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/extern_mod4.rs | 17 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/modules/mod.rs | 3 | ||||
-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 |