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);
}
}
#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"
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
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);
}
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,
{
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;
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
{
public:
static bool is_known (const std::string &attribute_path);
+ static tl::optional<std::string>
+ extract_string_literal (const AST::Attribute &attr);
};
enum CompilerPass