diff options
Diffstat (limited to 'gcc')
-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 |