@@ -2,7 +2,10 @@ use rustc_hir::attrs::{CoverageAttrKind, OptimizeAttr, SanitizerSet, UsedBy};
22use  rustc_session:: parse:: feature_err; 
33
44use  super :: prelude:: * ; 
5- use  crate :: session_diagnostics:: { NakedFunctionIncompatibleAttribute ,  NullOnExport } ; 
5+ use  crate :: session_diagnostics:: { 
6+     NakedFunctionIncompatibleAttribute ,  NullOnExport ,  NullOnObjcClass ,  NullOnObjcSelector , 
7+     ObjcClassExpectedStringLiteral ,  ObjcSelectorExpectedStringLiteral , 
8+ } ; 
69
710pub ( crate )  struct  OptimizeParser ; 
811
@@ -150,6 +153,70 @@ impl<S: Stage> SingleAttributeParser<S> for ExportNameParser {
150153    } 
151154} 
152155
156+ pub ( crate )  struct  ObjcClassParser ; 
157+ 
158+ impl < S :  Stage >  SingleAttributeParser < S >  for  ObjcClassParser  { 
159+     const  PATH :  & [ rustc_span:: Symbol ]  = & [ sym:: rustc_objc_class] ; 
160+     const  ATTRIBUTE_ORDER :  AttributeOrder  = AttributeOrder :: KeepInnermost ; 
161+     const  ON_DUPLICATE :  OnDuplicate < S >  = OnDuplicate :: Error ; 
162+     const  ALLOWED_TARGETS :  AllowedTargets  =
163+         AllowedTargets :: AllowList ( & [ Allow ( Target :: ForeignStatic ) ] ) ; 
164+     const  TEMPLATE :  AttributeTemplate  = template ! ( NameValueStr :  "ClassName" ) ; 
165+ 
166+     fn  convert ( cx :  & mut  AcceptContext < ' _ ,  ' _ ,  S > ,  args :  & ArgParser < ' _ > )  -> Option < AttributeKind >  { 
167+         let  Some ( nv)  = args. name_value ( )  else  { 
168+             cx. expected_name_value ( cx. attr_span ,  None ) ; 
169+             return  None ; 
170+         } ; 
171+         let  Some ( classname)  = nv. value_as_str ( )  else  { 
172+             // `#[rustc_objc_class = ...]` is expected to be used as an implementatioin detail 
173+             // inside a standard library macro, but `cx.expected_string_literal` exposes too much. 
174+             // Use a custom error message instead. 
175+             cx. emit_err ( ObjcClassExpectedStringLiteral  {  span :  nv. value_span  } ) ; 
176+             return  None ; 
177+         } ; 
178+         if  classname. as_str ( ) . contains ( '\0' )  { 
179+             // `#[rustc_objc_class = ...]` will be converted to a null-terminated string, 
180+             // so it may not contain any null characters. 
181+             cx. emit_err ( NullOnObjcClass  {  span :  nv. value_span  } ) ; 
182+             return  None ; 
183+         } 
184+         Some ( AttributeKind :: ObjcClass  {  classname,  span :  cx. attr_span  } ) 
185+     } 
186+ } 
187+ 
188+ pub ( crate )  struct  ObjcSelectorParser ; 
189+ 
190+ impl < S :  Stage >  SingleAttributeParser < S >  for  ObjcSelectorParser  { 
191+     const  PATH :  & [ rustc_span:: Symbol ]  = & [ sym:: rustc_objc_selector] ; 
192+     const  ATTRIBUTE_ORDER :  AttributeOrder  = AttributeOrder :: KeepInnermost ; 
193+     const  ON_DUPLICATE :  OnDuplicate < S >  = OnDuplicate :: Error ; 
194+     const  ALLOWED_TARGETS :  AllowedTargets  =
195+         AllowedTargets :: AllowList ( & [ Allow ( Target :: ForeignStatic ) ] ) ; 
196+     const  TEMPLATE :  AttributeTemplate  = template ! ( NameValueStr :  "methodName" ) ; 
197+ 
198+     fn  convert ( cx :  & mut  AcceptContext < ' _ ,  ' _ ,  S > ,  args :  & ArgParser < ' _ > )  -> Option < AttributeKind >  { 
199+         let  Some ( nv)  = args. name_value ( )  else  { 
200+             cx. expected_name_value ( cx. attr_span ,  None ) ; 
201+             return  None ; 
202+         } ; 
203+         let  Some ( methname)  = nv. value_as_str ( )  else  { 
204+             // `#[rustc_objc_selector = ...]` is expected to be used as an implementatioin detail 
205+             // inside a standard library macro, but `cx.expected_string_literal` exposes too much. 
206+             // Use a custom error message instead. 
207+             cx. emit_err ( ObjcSelectorExpectedStringLiteral  {  span :  nv. value_span  } ) ; 
208+             return  None ; 
209+         } ; 
210+         if  methname. as_str ( ) . contains ( '\0' )  { 
211+             // `#[rustc_objc_selector = ...]` will be converted to a null-terminated string, 
212+             // so it may not contain any null characters. 
213+             cx. emit_err ( NullOnObjcSelector  {  span :  nv. value_span  } ) ; 
214+             return  None ; 
215+         } 
216+         Some ( AttributeKind :: ObjcSelector  {  methname,  span :  cx. attr_span  } ) 
217+     } 
218+ } 
219+ 
153220#[ derive( Default ) ]  
154221pub ( crate )  struct  NakedParser  { 
155222    span :  Option < Span > , 
0 commit comments