@@ -3,8 +3,8 @@ use proc_macro2_diagnostics::{Diagnostic, SpanDiagnosticExt};
3
3
use quote:: quote;
4
4
use syn:: spanned:: Spanned ;
5
5
use syn:: {
6
- parenthesized, parse_macro_input, token, Attribute , Data , DeriveInput , Fields , FieldsNamed ,
7
- Ident , LitInt , Path , Variant ,
6
+ parenthesized, parse_macro_input, token, Attribute , Data , DeriveInput , Field , Fields ,
7
+ FieldsNamed , Ident , LitInt , Path , Variant ,
8
8
} ;
9
9
10
10
type Result < T > = std:: result:: Result < T , Diagnostic > ;
@@ -23,7 +23,14 @@ impl Repr {
23
23
let mut align = None ;
24
24
let mut primitive = None ;
25
25
for attr in attrs {
26
- if attr. path ( ) . is_ident ( "repr" ) {
26
+ let Some ( ident) = attr. path ( ) . get_ident ( ) else {
27
+ continue ;
28
+ } ;
29
+ if ident == "named" {
30
+ return Err ( attr
31
+ . span ( )
32
+ . error ( "`#[named]` attribute can only be applied to fields" ) ) ;
33
+ } else if ident == "repr" {
27
34
attr. parse_nested_meta ( |meta| {
28
35
if let Some ( ident) = meta. path . get_ident ( ) {
29
36
if ident == "C" {
@@ -69,7 +76,7 @@ fn ident_in_list<const N: usize>(ident: &Ident, list: [&'static str; N]) -> bool
69
76
list. iter ( ) . any ( |id| ident == id)
70
77
}
71
78
72
- #[ proc_macro_derive( AbstractType ) ]
79
+ #[ proc_macro_derive( AbstractType , attributes ( named ) ) ]
73
80
pub fn abstract_type_derive ( input : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
74
81
let input = parse_macro_input ! ( input as DeriveInput ) ;
75
82
match impl_abstract_type ( input) {
@@ -102,15 +109,30 @@ fn impl_abstract_type(ast: DeriveInput) -> Result<TokenStream> {
102
109
}
103
110
}
104
111
112
+ fn field_resolved_type ( field : & Field ) -> TokenStream {
113
+ let ty = & field. ty ;
114
+ let resolved_ty = quote ! { <#ty as :: binaryninja:: types:: AbstractType >:: resolve_type( ) } ;
115
+ if field. attrs . iter ( ) . any ( |attr| attr. path ( ) . is_ident ( "named" ) ) {
116
+ quote ! {
117
+ :: binaryninja:: types:: Type :: named_type_from_type(
118
+ stringify!( #ty) ,
119
+ & #resolved_ty
120
+ )
121
+ }
122
+ } else {
123
+ resolved_ty
124
+ }
125
+ }
126
+
105
127
fn field_arguments ( name : & Ident , fields : FieldsNamed ) -> Vec < TokenStream > {
106
128
fields
107
129
. named
108
130
. iter ( )
109
131
. map ( |field| {
110
132
let ident = field. ident . as_ref ( ) . unwrap ( ) ;
111
- let ty = & field. ty ;
133
+ let resolved_ty = field_resolved_type ( field) ;
112
134
quote ! {
113
- & <#ty as :: binaryninja :: types :: AbstractType > :: resolve_type ( ) ,
135
+ & #resolved_ty ,
114
136
stringify!( #ident) ,
115
137
:: std:: mem:: offset_of!( #name, #ident) as u64 ,
116
138
false ,
0 commit comments