aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorliushuyu <liushuyu011@gmail.com>2022-04-23 23:44:57 -0600
committerliushuyu <liushuyu011@gmail.com>2022-04-26 16:30:14 -0600
commit57725b57e51ca8d655c04f88487bcc7ba865d6f4 (patch)
treeccfe915181d7c33d477ddab5d88e2b37201b0f5c /gcc
parentd69dd650367fa7fcfac38001b6406c1bff2601e1 (diff)
downloadgcc-57725b57e51ca8d655c04f88487bcc7ba865d6f4.zip
gcc-57725b57e51ca8d655c04f88487bcc7ba865d6f4.tar.gz
gcc-57725b57e51ca8d655c04f88487bcc7ba865d6f4.tar.bz2
rust-session-manager: handle crate_name attribute
Signed-off-by: Zixing Liu <liushuyu011@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/rust-session-manager.cc73
-rw-r--r--gcc/rust/rust-session-manager.h2
-rw-r--r--gcc/rust/util/rust-hir-map.h13
-rw-r--r--gcc/testsuite/rust/compile/attr-mismatch-crate-name.rs4
-rw-r--r--gcc/testsuite/rust/compile/mismatch-crate-name.rs4
5 files changed, 83 insertions, 13 deletions
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 8876459..845a66a 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -405,7 +405,10 @@ Session::handle_option (
{
auto error = Error (Location (), std::string ());
if ((ret = validate_crate_name (arg, error)))
- options.set_crate_name (arg);
+ {
+ options.set_crate_name (arg);
+ options.crate_name_set_manually = true;
+ }
else
{
rust_assert (!error.message.empty ());
@@ -553,19 +556,9 @@ Session::parse_files (int num_files, const char **files)
filename = files[0];
auto crate_name = infer_crate_name (filename);
- Error error ((Location ()), std::string ());
rust_debug ("inferred crate name: %s", crate_name.c_str ());
- if (!validate_crate_name (crate_name, error))
- {
- // fake a linemapping so that we can show the filename
- linemap->start_file (filename, 0);
- linemap->start_line (0, 1);
- error.emit_error ();
- rust_inform (linemap->get_location (0),
- "crate name inferred from this file");
- linemap->stop ();
- return;
- }
+ // set the preliminary crate name here
+ // we will figure out the real crate name in `handle_crate_name`
options.set_crate_name (crate_name);
}
@@ -582,6 +575,57 @@ Session::parse_files (int num_files, const char **files)
* per-file. */
}
+void
+Session::handle_crate_name (AST::Crate parsed_crate)
+{
+ auto mappings = Analysis::Mappings::get ();
+ auto crate_name_changed = false;
+ auto error = Error (Location (), std::string ());
+
+ for (const auto &attr : parsed_crate.inner_attrs)
+ {
+ if (attr.get_path () != "crate_name")
+ continue;
+ if (!attr.has_attr_input ())
+ {
+ rust_error_at (attr.get_locus (),
+ "%<crate_name%> accepts one argument");
+ continue;
+ }
+
+ auto &literal
+ = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
+ const auto &msg_str = literal.get_literal ().as_string ();
+ if (!validate_crate_name (msg_str, error))
+ {
+ error.locus = attr.get_locus ();
+ error.emit_error ();
+ continue;
+ }
+
+ auto options = Session::get_instance ().options;
+ if (options.crate_name_set_manually && (options.crate_name != msg_str))
+ {
+ rust_error_at (attr.get_locus (),
+ "%<-frust-crate-name%> and %<#[crate_name]%> are "
+ "required to match, but %qs does not match %qs",
+ options.crate_name.c_str (), msg_str.c_str ());
+ }
+ crate_name_changed = true;
+ options.set_crate_name (msg_str);
+ mappings->set_crate_name (mappings->get_current_crate (), msg_str);
+ }
+
+ options.crate_name_set_manually |= crate_name_changed;
+ if (!options.crate_name_set_manually
+ && !validate_crate_name (options.crate_name, error))
+ {
+ error.emit_error ();
+ rust_inform (linemap->get_location (0),
+ "crate name inferred from this file");
+ }
+}
+
// Parses a single file with filename filename.
void
Session::parse_file (const char *filename)
@@ -606,6 +650,9 @@ Session::parse_file (const char *filename)
auto mappings = Analysis::Mappings::get ();
mappings->insert_ast_crate (&parsed_crate);
+ // handle crate name
+ handle_crate_name (parsed_crate);
+
if (options.dump_option_enabled (CompileOptions::LEXER_DUMP))
{
dump_lex (parser);
diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h
index 0c15711..97b5469 100644
--- a/gcc/rust/rust-session-manager.h
+++ b/gcc/rust/rust-session-manager.h
@@ -182,6 +182,7 @@ struct CompileOptions
* pointer width, vendor */
TargetOptions target_data;
std::string crate_name;
+ bool crate_name_set_manually = false;
bool enable_test = false;
bool debug_assertions = false;
bool proc_macro = false;
@@ -270,6 +271,7 @@ public:
const struct cl_option_handlers *handlers);
void parse_files (int num_files, const char **files);
void init_options ();
+ void handle_crate_name (AST::Crate parsed_crate);
/* This function saves the filename data into the session manager using the
* `move` semantics, and returns a C-style string referencing the input
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 19c2f0a..61b8c26 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -88,6 +88,19 @@ public:
return true;
}
+ // set crate name mid-compilation
+ // don't use this if setting crate name before Session::parse_files
+ bool set_crate_name (CrateNum crate_num, std::string name)
+ {
+ rust_assert (!name.empty ());
+ auto it = crate_names.find (crate_num);
+ if (it == crate_names.end ())
+ return false;
+
+ it->second.assign (name);
+ return true;
+ }
+
std::string get_current_crate_name () const
{
std::string name;
diff --git a/gcc/testsuite/rust/compile/attr-mismatch-crate-name.rs b/gcc/testsuite/rust/compile/attr-mismatch-crate-name.rs
new file mode 100644
index 0000000..1d40603
--- /dev/null
+++ b/gcc/testsuite/rust/compile/attr-mismatch-crate-name.rs
@@ -0,0 +1,4 @@
+// { dg-additional-options "-fdump-tree-gimple" }
+#![crate_name = "specified_name"]
+// { dg-final { scan-tree-dump-times {specified_name::main} 1 gimple } }
+fn main() {}
diff --git a/gcc/testsuite/rust/compile/mismatch-crate-name.rs b/gcc/testsuite/rust/compile/mismatch-crate-name.rs
new file mode 100644
index 0000000..e259b9e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/mismatch-crate-name.rs
@@ -0,0 +1,4 @@
+// { dg-additional-options "-frust-crate=another_name" }
+#![crate_name = "legit_name"]
+// { dg-error ".-frust-crate-name. and .#.crate_name.. are required to match, but .another_name. does not match .legit_name." "" { target *-*-* } .-1 }
+fn main() {}