diff options
author | liushuyu <liushuyu011@gmail.com> | 2022-04-23 23:44:57 -0600 |
---|---|---|
committer | liushuyu <liushuyu011@gmail.com> | 2022-04-26 16:30:14 -0600 |
commit | 57725b57e51ca8d655c04f88487bcc7ba865d6f4 (patch) | |
tree | ccfe915181d7c33d477ddab5d88e2b37201b0f5c /gcc | |
parent | d69dd650367fa7fcfac38001b6406c1bff2601e1 (diff) | |
download | gcc-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.cc | 73 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.h | 2 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.h | 13 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/attr-mismatch-crate-name.rs | 4 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/mismatch-crate-name.rs | 4 |
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() {} |