rustc_attr_parsing/attributes/
instruction_set.rs1use rustc_hir::attrs::InstructionSetAttr;
2
3use super::prelude::*;
4use crate::session_diagnostics;
5
6pub(crate) struct InstructionSetParser;
7
8impl<S: Stage> SingleAttributeParser<S> for InstructionSetParser {
9 const PATH: &[Symbol] = &[sym::instruction_set];
10 const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
11 Allow(Target::Fn),
12 Allow(Target::Closure),
13 Allow(Target::Method(MethodKind::Inherent)),
14 Allow(Target::Method(MethodKind::TraitImpl)),
15 Allow(Target::Method(MethodKind::Trait { body: true })),
16 ]);
17 const TEMPLATE: AttributeTemplate = ::rustc_feature::AttributeTemplate {
word: false,
list: Some(&["set"]),
one_of: &[],
name_value_str: None,
docs: Some("https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute"),
}template!(List: &["set"], "https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute");
18
19 fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
20 const POSSIBLE_SYMBOLS: &[Symbol] = &[sym::arm_a32, sym::arm_t32];
21 const POSSIBLE_ARM_SYMBOLS: &[Symbol] = &[sym::a32, sym::t32];
22 let maybe_meta_item = cx.expect_single_element_list(args, cx.attr_span)?;
23
24 let Some(meta_item) = maybe_meta_item.meta_item() else {
25 cx.adcx().expected_specific_argument(maybe_meta_item.span(), POSSIBLE_SYMBOLS);
26 return None;
27 };
28
29 let mut segments = meta_item.path().segments();
30
31 let Some(architecture) = segments.next() else {
32 cx.adcx().expected_specific_argument(meta_item.span(), POSSIBLE_SYMBOLS);
33 return None;
34 };
35
36 let Some(instruction_set) = segments.next() else {
37 cx.adcx().expected_specific_argument(architecture.span, POSSIBLE_SYMBOLS);
38 return None;
39 };
40
41 let instruction_set = match architecture.name {
42 sym::arm => {
43 if !cx.sess.target.has_thumb_interworking {
44 cx.dcx().emit_err(session_diagnostics::UnsupportedInstructionSet {
45 span: cx.attr_span,
46 instruction_set: sym::arm,
47 current_target: &cx.sess.opts.target_triple,
48 });
49 return None;
50 }
51 match instruction_set.name {
52 sym::a32 => InstructionSetAttr::ArmA32,
53 sym::t32 => InstructionSetAttr::ArmT32,
54 _ => {
55 cx.adcx()
56 .expected_specific_argument(instruction_set.span, POSSIBLE_ARM_SYMBOLS);
57 return None;
58 }
59 }
60 }
61 _ => {
62 cx.adcx().expected_specific_argument(architecture.span, POSSIBLE_SYMBOLS);
63 return None;
64 }
65 };
66
67 Some(AttributeKind::InstructionSet(instruction_set))
68 }
69}