]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Improve handling of AttrInputLiteral
authorOwen Avery <powerboat9.gamer@gmail.com>
Tue, 5 Aug 2025 20:44:02 +0000 (16:44 -0400)
committerArthur Cohen <arthur.cohen@embecosm.com>
Thu, 30 Oct 2025 19:58:34 +0000 (20:58 +0100)
Also adjusts a few error messages to be more in line with rustc (and
more amenable to extract_string_literal usage).

gcc/rust/ChangeLog:

* util/rust-attributes.cc (Attributes::extract_string_literal):
New function definition.
* util/rust-attributes.h (Attributes::extract_string_literal):
New function declaration.
* ast/rust-collect-lang-items.cc (get_lang_item_attr): Use
extract_string_literal.
* backend/rust-compile-base.cc: Include "rust-attributes.h".
(HIRCompileBase::handle_link_section_attribute_on_fndecl):
Use extract_string_literal.
(HIRCompileBase::handle_must_use_attribute_on_fndecl): Likewise.
* hir/rust-ast-lower-base.cc
(ASTLoweringBase::handle_lang_item_attribute): Likewise.
* rust-session-manager.cc (Session::handle_crate_name):
Likewise.

Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
gcc/rust/ast/rust-collect-lang-items.cc
gcc/rust/backend/rust-compile-base.cc
gcc/rust/hir/rust-ast-lower-base.cc
gcc/rust/rust-session-manager.cc
gcc/rust/util/rust-attributes.cc
gcc/rust/util/rust-attributes.h

index 306c6f747e2b7d6223d68ea79f07234bf8aaf5c4..1efe26f8dfd3a774c3b59b4f34aabfbb58e48968 100644 (file)
@@ -43,18 +43,16 @@ get_lang_item_attr (const T &maybe_lang_item)
          continue;
        }
 
-      bool is_lang_item = str_path == Values::Attributes::LANG
-                         && attr.has_attr_input ()
-                         && attr.get_attr_input ().get_attr_input_type ()
-                              == AST::AttrInput::AttrInputType::LITERAL;
+      bool is_lang_item = str_path == Values::Attributes::LANG;
 
       if (is_lang_item)
        {
-         auto &literal
-           = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
-         const auto &lang_item_type_str = literal.get_literal ().as_string ();
+         auto lang_item_type_str
+           = Analysis::Attributes::extract_string_literal (attr);
 
-         return LangItem::Parse (lang_item_type_str);
+         rust_assert (lang_item_type_str.has_value ());
+
+         return LangItem::Parse (*lang_item_type_str);
        }
     }
 
index 73c34b269b7e3b48b5fc6564296911dcf5f52027..d1db58e32844574a872e25ff74a0fe6c03329290 100644 (file)
@@ -32,6 +32,7 @@
 #include "rust-type-util.h"
 #include "rust-compile-implitem.h"
 #include "rust-attribute-values.h"
+#include "rust-attributes.h"
 #include "rust-immutable-name-resolution-context.h"
 
 #include "fold-const.h"
@@ -251,25 +252,21 @@ void
 HIRCompileBase::handle_link_section_attribute_on_fndecl (
   tree fndecl, const AST::Attribute &attr)
 {
-  if (!attr.has_attr_input ())
+  auto msg_str = Analysis::Attributes::extract_string_literal (attr);
+
+  if (!msg_str.has_value ())
     {
       rust_error_at (attr.get_locus (),
-                    "%<link_section%> expects exactly one argment");
+                    "malformed %<link_section%> attribute input");
       return;
     }
 
-  rust_assert (attr.get_attr_input ().get_attr_input_type ()
-              == AST::AttrInput::AttrInputType::LITERAL);
-
-  auto &literal = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
-  const auto &msg_str = literal.get_literal ().as_string ();
-
   if (decl_section_name (fndecl))
     {
       rust_warning_at (attr.get_locus (), 0, "section name redefined");
     }
 
-  set_decl_section_name (fndecl, msg_str.c_str ());
+  set_decl_section_name (fndecl, msg_str->c_str ());
 }
 
 void
@@ -416,13 +413,10 @@ HIRCompileBase::handle_must_use_attribute_on_fndecl (tree fndecl,
 
   if (attr.has_attr_input ())
     {
-      rust_assert (attr.get_attr_input ().get_attr_input_type ()
-                  == AST::AttrInput::AttrInputType::LITERAL);
+      auto msg_str = Analysis::Attributes::extract_string_literal (attr);
+      rust_assert (msg_str.has_value ());
 
-      auto &literal
-       = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
-      const auto &msg_str = literal.get_literal ().as_string ();
-      tree message = build_string (msg_str.size (), msg_str.c_str ());
+      tree message = build_string (msg_str->size (), msg_str->c_str ());
 
       value = tree_cons (nodiscard, message, NULL_TREE);
     }
index 7cbef42b5e4fc65286f54dbdc557e706f0e9db38..9445658300cd864487db8f797cc15153983b4211 100644 (file)
@@ -850,9 +850,10 @@ void
 ASTLoweringBase::handle_lang_item_attribute (const ItemWrapper &item,
                                             const AST::Attribute &attr)
 {
-  auto &literal = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
-  const auto &lang_item_type_str = literal.get_literal ().as_string ();
-  auto lang_item_type = LangItem::Parse (lang_item_type_str);
+  auto lang_item_type_str = Analysis::Attributes::extract_string_literal (attr);
+  rust_assert (lang_item_type_str.has_value ());
+
+  auto lang_item_type = LangItem::Parse (*lang_item_type_str);
 
   if (lang_item_type)
     mappings.insert_lang_item (*lang_item_type,
index 17f9c06040d0370110c291a8109d3e014b9afbf8..c88f46757535bd692c113ac9fb549f0bf03c8621 100644 (file)
@@ -422,32 +422,31 @@ Session::handle_crate_name (const char *filename,
     {
       if (attr.get_path () != "crate_name")
        continue;
-      if (!attr.has_attr_input ())
+
+      auto msg_str = Analysis::Attributes::extract_string_literal (attr);
+      if (!msg_str.has_value ())
        {
          rust_error_at (attr.get_locus (),
-                        "%<crate_name%> accepts one argument");
+                        "malformed %<crate_name%> attribute input");
          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))
+      if (!validate_crate_name (*msg_str, error))
        {
          error.locus = attr.get_locus ();
          error.emit ();
          continue;
        }
 
-      if (options.crate_name_set_manually && (options.crate_name != msg_str))
+      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 ());
+                        options.crate_name.c_str (), msg_str->c_str ());
        }
       crate_name_found = true;
-      options.set_crate_name (msg_str);
+      options.set_crate_name (*msg_str);
     }
 
   options.crate_name_set_manually |= crate_name_found;
index c846c2d5c33c818fd713f8496536af4358294e4a..265391827e428ae617b11028f01af02ef88a6bdd 100644 (file)
@@ -38,6 +38,31 @@ Attributes::is_known (const std::string &attribute_path)
   return !lookup.is_error ();
 }
 
+tl::optional<std::string>
+Attributes::extract_string_literal (const AST::Attribute &attr)
+{
+  if (!attr.has_attr_input ())
+    return tl::nullopt;
+
+  auto &attr_input = attr.get_attr_input ();
+
+  if (attr_input.get_attr_input_type ()
+      != AST::AttrInput::AttrInputType::LITERAL)
+    return tl::nullopt;
+
+  auto &literal_expr
+    = static_cast<AST::AttrInputLiteral &> (attr_input).get_literal ();
+
+  auto lit_type = literal_expr.get_lit_type ();
+
+  // TODO: bring escape sequence handling out of lexing?
+  if (lit_type != AST::Literal::LitType::STRING
+      && lit_type != AST::Literal::LitType::RAW_STRING)
+    return tl::nullopt;
+
+  return literal_expr.as_string ();
+}
+
 using Attrs = Values::Attributes;
 
 // https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_feature/builtin_attrs.rs.html#248
index db8fe234778c5e8e92df5568f00eb008b6778757..da3b0cd25810b5a263725d883040622831e40328 100644 (file)
@@ -29,6 +29,8 @@ class Attributes
 {
 public:
   static bool is_known (const std::string &attribute_path);
+  static tl::optional<std::string>
+  extract_string_literal (const AST::Attribute &attr);
 };
 
 enum CompilerPass