On 5/28/25 12:49, Manos Pitsidianakis wrote:
It's not too large, overall.
#[repr(C)]
-#[derive(qemu_api_macros::Object)]
+#[derive(qemu_api_macros::Object, qemu_api_macros::DeviceProperties)]
Is there more to be derived that is useful for Devices? Maybe the
macro can be DeviceState or Device.
VMStateDescription and the realize callback, I think.
Ok, pick the name that you prefer.
Can you change the name to be a "normal" string and change it to a C literal in
the macro?
That'd be neat, it should be possible to create a cstr literal token
and error out if the input str literal cannot be represented as a
cstr.
Yes, shouldn't be hard. If it is hard, you could resurrect the c_str module
and use ::qemu_api::c_str!(#string).
I would also merge the files at this point, but no hurry.
+#[derive(Debug)]
+struct DeviceProperty {
+ name: Option<syn::LitCStr>,
+ qdev_prop: Option<syn::Path>,
+ assert_type: Option<proc_macro2::TokenStream>,
+ bitnr: Option<syn::Expr>,
+ defval: Option<syn::Expr>,
+}
+
+impl Parse for DeviceProperty {
Can you look into using https://docs.rs/crate/attrs/latest for parsing?
(attrs doesn't support LitCStr btw)
I think we can do without it for now, even if this patch is not
cleaned up (for example it has unwraps instead of proper panic
messages or error handling) it does not end up very complex as far as
attribute parsing is concerned.
I'm fine with either approach though.
Ok, I'm fine with the manual parsing as well; just use Result<>
instead of panicking.
+#[proc_macro_derive(DeviceProperties, attributes(property, bool_property))]
+pub fn derive_device_properties(input: TokenStream) -> TokenStream {
Do you need to handle errors in the parsing of attributes?...
+ _other => unreachable!(),
This should be literally unreachable IIUC, because only property names
declared in the attributes part of `#[proc_macro_derive(...
attributes(__))]` would get accepted by the compiler and passed to the
derive macro.
You're referring to
+ other => unreachable!("Got unexpected DeviceProperty attribute
`{}`", other),
and indeed this one is good as is. The "_other => unreachable!()"
line above, instead, comes from matching on input.data and it can
be replaced with the existing function get_fields().
Paolo