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