|
1 | 1 | use rustc_feature::{AttributeTemplate, template}; |
2 | | -use rustc_hir::attrs::AttributeKind; |
3 | 2 | use rustc_hir::attrs::AttributeKind::{LinkName,LinkOrdinal,LinkSection}; |
| 3 | +use rustc_hir::attrs::{AttributeKind,Linkage}; |
4 | 4 | use rustc_span::{Span,Symbol, sym}; |
5 | 5 |
|
6 | 6 | usecrate::attributes::{ |
@@ -129,3 +129,77 @@ impl<S: Stage> SingleAttributeParser<S> for LinkOrdinalParser { |
129 | 129 | Some(LinkOrdinal{ ordinal,span: cx.attr_span}) |
130 | 130 | } |
131 | 131 | } |
| 132 | + |
| 133 | +pub(crate)structLinkageParser; |
| 134 | + |
| 135 | +impl<S:Stage>SingleAttributeParser<S>forLinkageParser{ |
| 136 | +constPATH:&[Symbol] = &[sym::linkage]; |
| 137 | + |
| 138 | +constATTRIBUTE_ORDER:AttributeOrder = AttributeOrder::KeepOutermost; |
| 139 | + |
| 140 | +constON_DUPLICATE:OnDuplicate<S> = OnDuplicate::Error; |
| 141 | + |
| 142 | +constTEMPLATE:AttributeTemplate = template!(NameValueStr:[ |
| 143 | +"available_externally", |
| 144 | +"common", |
| 145 | +"extern_weak", |
| 146 | +"external", |
| 147 | +"internal", |
| 148 | +"linkonce", |
| 149 | +"linkonce_odr", |
| 150 | +"weak", |
| 151 | +"weak_odr", |
| 152 | +]); |
| 153 | + |
| 154 | +fnconvert(cx:&mutAcceptContext<'_,'_,S>,args:&ArgParser<'_>) -> Option<AttributeKind>{ |
| 155 | +letSome(name_value) = args.name_value()else{ |
| 156 | + cx.expected_name_value(cx.attr_span,Some(sym::linkage)); |
| 157 | +returnNone; |
| 158 | +}; |
| 159 | + |
| 160 | +letSome(value) = name_value.value_as_str()else{ |
| 161 | + cx.expected_string_literal(name_value.value_span,Some(name_value.value_as_lit())); |
| 162 | +returnNone; |
| 163 | +}; |
| 164 | + |
| 165 | +// Use the names from src/llvm/docs/LangRef.rst here. Most types are only |
| 166 | +// applicable to variable declarations and may not really make sense for |
| 167 | +// Rust code in the first place but allow them anyway and trust that the |
| 168 | +// user knows what they're doing. Who knows, unanticipated use cases may pop |
| 169 | +// up in the future. |
| 170 | +// |
| 171 | +// ghost, dllimport, dllexport and linkonce_odr_autohide are not supported |
| 172 | +// and don't have to be, LLVM treats them as no-ops. |
| 173 | +let linkage = match value { |
| 174 | + sym::available_externally => Linkage::AvailableExternally, |
| 175 | + sym::common => Linkage::Common, |
| 176 | + sym::extern_weak => Linkage::ExternalWeak, |
| 177 | + sym::external => Linkage::External, |
| 178 | + sym::internal => Linkage::Internal, |
| 179 | + sym::linkonce => Linkage::LinkOnceAny, |
| 180 | + sym::linkonce_odr => Linkage::LinkOnceODR, |
| 181 | + sym::weak => Linkage::WeakAny, |
| 182 | + sym::weak_odr => Linkage::WeakODR, |
| 183 | + |
| 184 | + _ => { |
| 185 | + cx.expected_specific_argument( |
| 186 | + name_value.value_span, |
| 187 | +vec![ |
| 188 | +"available_externally", |
| 189 | +"common", |
| 190 | +"extern_weak", |
| 191 | +"external", |
| 192 | +"internal", |
| 193 | +"linkonce", |
| 194 | +"linkonce_odr", |
| 195 | +"weak", |
| 196 | +"weak_odr", |
| 197 | +], |
| 198 | +); |
| 199 | +returnNone; |
| 200 | +} |
| 201 | +}; |
| 202 | + |
| 203 | +Some(AttributeKind::Linkage(linkage, cx.attr_span)) |
| 204 | +} |
| 205 | +} |
0 commit comments