aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust
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 /gcc/rust
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>
Diffstat (limited to 'gcc/rust')
-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
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;