@@ -6,7 +6,7 @@ use rustc_span::{Span, Symbol, sym};
6
6
use super :: { AcceptMapping , AttributeOrder , AttributeParser , OnDuplicate , SingleAttributeParser } ;
7
7
use crate :: context:: { AcceptContext , FinalizeContext , Stage } ;
8
8
use crate :: parser:: ArgParser ;
9
- use crate :: session_diagnostics:: NakedFunctionIncompatibleAttribute ;
9
+ use crate :: session_diagnostics:: { NakedFunctionIncompatibleAttribute , NullOnExport } ;
10
10
11
11
pub ( crate ) struct OptimizeParser ;
12
12
@@ -59,6 +59,33 @@ impl<S: Stage> SingleAttributeParser<S> for ColdParser {
59
59
}
60
60
}
61
61
62
+ pub ( crate ) struct ExportNameParser ;
63
+
64
+ impl < S : Stage > SingleAttributeParser < S > for ExportNameParser {
65
+ const PATH : & [ rustc_span:: Symbol ] = & [ sym:: export_name] ;
66
+ const ATTRIBUTE_ORDER : AttributeOrder = AttributeOrder :: KeepFirst ;
67
+ const ON_DUPLICATE : OnDuplicate < S > = OnDuplicate :: WarnButFutureError ;
68
+ const TEMPLATE : AttributeTemplate = template ! ( NameValueStr : "name" ) ;
69
+
70
+ fn convert ( cx : & mut AcceptContext < ' _ , ' _ , S > , args : & ArgParser < ' _ > ) -> Option < AttributeKind > {
71
+ let Some ( nv) = args. name_value ( ) else {
72
+ cx. expected_name_value ( cx. attr_span , None ) ;
73
+ return None ;
74
+ } ;
75
+ let Some ( name) = nv. value_as_str ( ) else {
76
+ cx. expected_string_literal ( nv. value_span , Some ( nv. value_as_lit ( ) ) ) ;
77
+ return None ;
78
+ } ;
79
+ if name. as_str ( ) . contains ( '\0' ) {
80
+ // `#[export_name = ...]` will be converted to a null-terminated string,
81
+ // so it may not contain any null characters.
82
+ cx. emit_err ( NullOnExport { span : cx. attr_span } ) ;
83
+ return None ;
84
+ }
85
+ Some ( AttributeKind :: ExportName { name, span : cx. attr_span } )
86
+ }
87
+ }
88
+
62
89
#[ derive( Default ) ]
63
90
pub ( crate ) struct NakedParser {
64
91
span : Option < Span > ,
0 commit comments