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