xref: /aosp_15_r20/external/mesa3d/src/nouveau/compiler/nak/ir_proc.rs (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 // Copyright © 2023 Collabora, Ltd.
2 // SPDX-License-Identifier: MIT
3 
4 extern crate proc_macro;
5 extern crate proc_macro2;
6 #[macro_use]
7 extern crate quote;
8 extern crate syn;
9 
10 use compiler_proc::as_slice::*;
11 use proc_macro::TokenStream;
12 use proc_macro2::{TokenStream as TokenStream2};
13 use syn::*;
14 
15 #[proc_macro_derive(SrcsAsSlice, attributes(src_type))]
derive_srcs_as_slice(input: TokenStream) -> TokenStream16 pub fn derive_srcs_as_slice(input: TokenStream) -> TokenStream {
17     derive_as_slice(input, "Src", "src_type", "SrcType")
18 }
19 
20 #[proc_macro_derive(DstsAsSlice, attributes(dst_type))]
derive_dsts_as_slice(input: TokenStream) -> TokenStream21 pub fn derive_dsts_as_slice(input: TokenStream) -> TokenStream {
22     derive_as_slice(input, "Dst", "dst_type", "DstType")
23 }
24 
25 #[proc_macro_derive(DisplayOp)]
enum_derive_display_op(input: TokenStream) -> TokenStream26 pub fn enum_derive_display_op(input: TokenStream) -> TokenStream {
27     let DeriveInput { ident, data, .. } = parse_macro_input!(input);
28 
29     if let Data::Enum(e) = data {
30         let mut fmt_dsts_cases = TokenStream2::new();
31         let mut fmt_op_cases = TokenStream2::new();
32         for v in e.variants {
33             let case = v.ident;
34             fmt_dsts_cases.extend(quote! {
35                 #ident::#case(x) => x.fmt_dsts(f),
36             });
37             fmt_op_cases.extend(quote! {
38                 #ident::#case(x) => x.fmt_op(f),
39             });
40         }
41         quote! {
42             impl DisplayOp for #ident {
43                 fn fmt_dsts(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44                     match self {
45                         #fmt_dsts_cases
46                     }
47                 }
48 
49                 fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50                     match self {
51                         #fmt_op_cases
52                     }
53                 }
54             }
55         }
56         .into()
57     } else {
58         panic!("Not an enum type");
59     }
60 }
61 
62 #[proc_macro_derive(FromVariants)]
derive_from_variants(input: TokenStream) -> TokenStream63 pub fn derive_from_variants(input: TokenStream) -> TokenStream {
64     let DeriveInput { ident, data, .. } = parse_macro_input!(input);
65     let enum_type = ident;
66 
67     let mut impls = TokenStream2::new();
68 
69     if let Data::Enum(e) = data {
70         for v in e.variants {
71             let var_ident = v.ident;
72             let from_type = match v.fields {
73                 Fields::Unnamed(FieldsUnnamed { unnamed, .. }) => unnamed,
74                 _ => panic!("Expected Op(OpFoo)"),
75             };
76 
77             let quote = quote! {
78                 impl From<#from_type> for #enum_type {
79                     fn from (op: #from_type) -> #enum_type {
80                         #enum_type::#var_ident(op)
81                     }
82                 }
83             };
84 
85             impls.extend(quote);
86         }
87     }
88 
89     impls.into()
90 }
91