public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] rust-session-manager: handle crate_name attribute
@ 2022-06-08 12:38 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 12:38 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:57725b57e51ca8d655c04f88487bcc7ba865d6f4

commit 57725b57e51ca8d655c04f88487bcc7ba865d6f4
Author: liushuyu <liushuyu011@gmail.com>
Date:   Sat Apr 23 23:44:57 2022 -0600

    rust-session-manager: handle crate_name attribute
    
    Signed-off-by: Zixing Liu <liushuyu011@gmail.com>

Diff:
---
 gcc/rust/rust-session-manager.cc                   | 73 ++++++++++++++++++----
 gcc/rust/rust-session-manager.h                    |  2 +
 gcc/rust/util/rust-hir-map.h                       | 13 ++++
 .../rust/compile/attr-mismatch-crate-name.rs       |  4 ++
 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 887645954de..845a66ae04c 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 0c15711ab0e..97b546922cf 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 19c2f0aae38..61b8c26c9b9 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 00000000000..1d406031fee
--- /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 00000000000..e259b9e46cc
--- /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() {}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-08 12:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 12:38 [gcc/devel/rust/master] rust-session-manager: handle crate_name attribute Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).