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 /gcc/rust | |
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>
Diffstat (limited to 'gcc/rust')
-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 |
4 files changed, 61 insertions, 12 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; |