Attribute
MetaItemPathExpr::to_attribute () const
{
- rust_assert (expr->is_literal ());
- auto &lit = static_cast<LiteralExpr &> (*expr);
- return Attribute (path, std::unique_ptr<AttrInputLiteral> (
- new AttrInputLiteral (lit)));
+ auto input = std::make_unique<AttrInputExpr> (expr->clone_expr ());
+ return Attribute (path, std::move (input));
}
std::vector<Attribute>
for (auto it = items.begin () + 1; it != items.end (); ++it)
{
- if ((*it)->get_kind () == MetaItemInner::Kind::MetaItem
- && static_cast<MetaItem &> (**it).get_item_kind ()
- == MetaItem::ItemKind::PathExpr
- && !static_cast<MetaItemPathExpr &> (**it).get_expr ().is_literal ())
- continue;
+ auto &item = **it;
- Attribute attr = (*it)->to_attribute ();
+ Attribute attr = item.to_attribute ();
if (attr.is_empty ())
{
/* TODO should this be an error that causes us to chuck out
if (attr.check_cfg_predicate (session))
{
+ // Key has been found we need to remove the conditional part of
+ // the attribute and insert the content back
+
// split off cfg_attr
AST::AttrVec new_attrs = attr.separate_cfg_attrs ();
*/
i--;
}
+ else
+ {
+ // Key has not been found, remove the whole attribute
+ attrs.erase (attrs.begin () + i);
+ i--;
+ }
/* do something - if feature (first token in tree) is in fact enabled,
* make tokens listed afterwards into attributes. i.e.: for
void
AttributeChecker::visit (AST::Attribute &attribute)
{
- if (!attribute.empty_input ())
+ auto &session = Session::get_instance ();
+ if (attribute.get_path () == Values::Attributes::CFG_ATTR)
{
- const auto &attr_input = attribute.get_attr_input ();
- auto type = attr_input.get_attr_input_type ();
- if (type == AST::AttrInput::AttrInputType::TOKEN_TREE)
- {
- const auto &option = static_cast<const AST::DelimTokenTree &> (
- attribute.get_attr_input ());
- std::unique_ptr<AST::AttrInputMetaItemContainer> meta_item (
- option.parse_to_meta_item ());
- AST::DefaultASTVisitor::visit (meta_item);
- }
+ if (!attribute.is_parsed_to_meta_item ())
+ attribute.parse_attr_to_meta_item ();
+ if (!attribute.check_cfg_predicate (session))
+ return; // Do not emit errors for attribute that'll get stripped.
}
- auto result_opt = identify_builtin (attribute);
-
- // This checker does not check non-builtin attributes
- if (!result_opt.has_value ())
- return;
- auto result = result_opt.value ();
+ if (auto builtin = identify_builtin (attribute))
+ {
+ auto result = builtin.value ();
+ // TODO: Add checks here for each builtin attribute
+ // TODO: Have an enum of builtins as well, switching on strings is
+ // annoying and costly
+ if (result.name == Attrs::DOC)
+ check_doc_attribute (attribute);
+ else if (result.name == Attrs::DEPRECATED)
+ check_deprecated_attribute (attribute);
+ }
- // TODO: Add checks here for each builtin attribute
- // TODO: Have an enum of builtins as well, switching on strings is annoying
- // and costly
- if (result.name == Attrs::DOC)
- check_doc_attribute (attribute);
- else if (result.name == Attrs::DEPRECATED)
- check_deprecated_attribute (attribute);
+ AST::DefaultASTVisitor::visit (attribute);
}
void
#[cfg_attr(target_arch = "x86_64", path = (target_arch = "x86", path = "x86.rs"))]
mod imp {}
-// { dg-error "malformed .path. attribute input" "" { target *-*-* } .-2 }
+// { dg-error "malformed .path. attribute input" "" { target { x86_64-*-* && { lp64 } } } .-2 }
+// { dg-error "cannot find value .target_arch. in this scope" "" { target { x86_64-*-* && { lp64 } } } .-3 }
+// { dg-error "cannot find value .path. in this scope" "" { target { x86_64-*-* && { lp64 } } } .-4 }