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( 20 not(any(target_vendor = "apple", target_os = "windows")), 21 link_section = ".init_array" 22 )] 23 #[cfg_attr(target_vendor = "apple", link_section = "__DATA,__mod_init_func")] 24 #[cfg_attr(target_os = "windows", link_section = ".CRT$XCU")] 25 pub static #module_static: extern "C" fn() = { 26 extern "C" fn __register() { 27 unsafe { 28 ::qemu_api::bindings::type_register_static(&<#name as ::qemu_api::definitions::ObjectImpl>::TYPE_INFO); 29 } 30 } 31 32 extern "C" fn __load() { 33 unsafe { 34 ::qemu_api::bindings::register_module_init( 35 Some(__register), 36 ::qemu_api::bindings::module_init_type::MODULE_INIT_QOM 37 ); 38 } 39 } 40 41 __load 42 }; 43 }; 44 45 TokenStream::from(expanded) 46 } 47