xref: /openbmc/qemu/rust/qemu-api-macros/src/lib.rs (revision 2b74dd91)
1*2b74dd91SManos Pitsidianakis // Copyright 2024, Linaro Limited
2*2b74dd91SManos Pitsidianakis // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
3*2b74dd91SManos Pitsidianakis // SPDX-License-Identifier: GPL-2.0-or-later
4*2b74dd91SManos Pitsidianakis 
5*2b74dd91SManos Pitsidianakis use proc_macro::TokenStream;
6*2b74dd91SManos Pitsidianakis use quote::{format_ident, quote};
7*2b74dd91SManos Pitsidianakis use syn::{parse_macro_input, DeriveInput};
8*2b74dd91SManos Pitsidianakis 
9*2b74dd91SManos Pitsidianakis #[proc_macro_derive(Object)]
10*2b74dd91SManos Pitsidianakis pub fn derive_object(input: TokenStream) -> TokenStream {
11*2b74dd91SManos Pitsidianakis     let input = parse_macro_input!(input as DeriveInput);
12*2b74dd91SManos Pitsidianakis 
13*2b74dd91SManos Pitsidianakis     let name = input.ident;
14*2b74dd91SManos Pitsidianakis     let module_static = format_ident!("__{}_LOAD_MODULE", name);
15*2b74dd91SManos Pitsidianakis 
16*2b74dd91SManos Pitsidianakis     let expanded = quote! {
17*2b74dd91SManos Pitsidianakis         #[allow(non_upper_case_globals)]
18*2b74dd91SManos Pitsidianakis         #[used]
19*2b74dd91SManos Pitsidianakis         #[cfg_attr(target_os = "linux", link_section = ".ctors")]
20*2b74dd91SManos Pitsidianakis         #[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
21*2b74dd91SManos Pitsidianakis         #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")]
22*2b74dd91SManos Pitsidianakis         pub static #module_static: extern "C" fn() = {
23*2b74dd91SManos Pitsidianakis             extern "C" fn __register() {
24*2b74dd91SManos Pitsidianakis                 unsafe {
25*2b74dd91SManos Pitsidianakis                     ::qemu_api::bindings::type_register_static(&<#name as ::qemu_api::definitions::ObjectImpl>::TYPE_INFO);
26*2b74dd91SManos Pitsidianakis                 }
27*2b74dd91SManos Pitsidianakis             }
28*2b74dd91SManos Pitsidianakis 
29*2b74dd91SManos Pitsidianakis             extern "C" fn __load() {
30*2b74dd91SManos Pitsidianakis                 unsafe {
31*2b74dd91SManos Pitsidianakis                     ::qemu_api::bindings::register_module_init(
32*2b74dd91SManos Pitsidianakis                         Some(__register),
33*2b74dd91SManos Pitsidianakis                         ::qemu_api::bindings::module_init_type::MODULE_INIT_QOM
34*2b74dd91SManos Pitsidianakis                     );
35*2b74dd91SManos Pitsidianakis                 }
36*2b74dd91SManos Pitsidianakis             }
37*2b74dd91SManos Pitsidianakis 
38*2b74dd91SManos Pitsidianakis             __load
39*2b74dd91SManos Pitsidianakis         };
40*2b74dd91SManos Pitsidianakis     };
41*2b74dd91SManos Pitsidianakis 
42*2b74dd91SManos Pitsidianakis     TokenStream::from(expanded)
43*2b74dd91SManos Pitsidianakis }
44