rustc_attr_parsing/attributes/
codegen_attrs.rs

1use rustc_attr_data_structures::{AttributeKind, OptimizeAttr};
2use rustc_feature::{AttributeTemplate, template};
3use rustc_span::sym;
4
5use super::{AttributeOrder, OnDuplicate, SingleAttributeParser};
6use crate::context::{AcceptContext, Stage};
7use crate::parser::ArgParser;
8
9pub(crate) struct OptimizeParser;
10
11impl<S: Stage> SingleAttributeParser<S> for OptimizeParser {
12    const PATH: &[rustc_span::Symbol] = &[sym::optimize];
13    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
14    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
15    const TEMPLATE: AttributeTemplate = template!(List: "size|speed|none");
16
17    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
18        let Some(list) = args.list() else {
19            cx.expected_list(cx.attr_span);
20            return None;
21        };
22
23        let Some(single) = list.single() else {
24            cx.expected_single_argument(list.span);
25            return None;
26        };
27
28        let res = match single.meta_item().and_then(|i| i.path().word().map(|i| i.name)) {
29            Some(sym::size) => OptimizeAttr::Size,
30            Some(sym::speed) => OptimizeAttr::Speed,
31            Some(sym::none) => OptimizeAttr::DoNotOptimize,
32            _ => {
33                cx.expected_specific_argument(single.span(), vec!["size", "speed", "none"]);
34                OptimizeAttr::Default
35            }
36        };
37
38        Some(AttributeKind::Optimize(res, cx.attr_span))
39    }
40}
41
42pub(crate) struct ColdParser;
43
44impl<S: Stage> SingleAttributeParser<S> for ColdParser {
45    const PATH: &[rustc_span::Symbol] = &[sym::cold];
46    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
47    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
48    const TEMPLATE: AttributeTemplate = template!(Word);
49
50    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
51        if !args.no_args() {
52            cx.expected_no_args(args.span().unwrap_or(cx.attr_span));
53            return None;
54        };
55
56        Some(AttributeKind::Cold(cx.attr_span))
57    }
58}
59
60pub(crate) struct NoMangleParser;
61
62impl<S: Stage> SingleAttributeParser<S> for NoMangleParser {
63    const PATH: &[rustc_span::Symbol] = &[sym::no_mangle];
64    const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
65    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
66    const TEMPLATE: AttributeTemplate = template!(Word);
67
68    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
69        if !args.no_args() {
70            cx.expected_no_args(args.span().unwrap_or(cx.attr_span));
71            return None;
72        };
73
74        Some(AttributeKind::NoMangle(cx.attr_span))
75    }
76}