Skip to content

Commit 3b2f88e

Browse files
committed
Add traits on empty structs
1 parent a79e315 commit 3b2f88e

10 files changed

Lines changed: 64 additions & 1 deletion

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ std::string Converter::EmitMethodsOnPtr() {
7676
std::string Converter::EmitOpaqueRecords() {
7777
std::string out;
7878
record_decls_.ForEachUndefined([&](const std::string &name) {
79+
out += "#[derive(Clone, Copy, Default, ByteRepr)]";
7980
out += "pub struct ";
8081
out += name;
8182
out += ";\n";

‎libcc2rs-macros/src/byte_repr.rs‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
use proc_macro::TokenStream;
5+
use syn::{Data, DeriveInput, Fields, parse_macro_input};
6+
7+
pub fn expand(input: TokenStream) -> TokenStream {
8+
let input = parse_macro_input!(input as DeriveInput);
9+
let name = &input.ident;
10+
let empty = match &input.data {
11+
Data::Struct(s) => match &s.fields {
12+
Fields::Unit => true,
13+
Fields::Named(f) => f.named.is_empty(),
14+
Fields::Unnamed(f) => f.unnamed.is_empty(),
15+
},
16+
_ => false,
17+
};
18+
if !empty {
19+
panic!("derive(ByteRepr) is only supported on empty structs, `{name}` is not empty");
20+
}
21+
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
22+
quote::quote! {
23+
impl #impl_generics ::libcc2rs::ByteRepr for #name #ty_generics #where_clause {
24+
#[inline]
25+
fn byte_size() -> usize {
26+
1
27+
}
28+
}
29+
}
30+
.into()
31+
}

‎libcc2rs-macros/src/lib.rs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use proc_macro::TokenStream;
55

6+
mod byte_repr;
67
mod goto;
78
mod state_machine;
89
mod switch;
@@ -79,3 +80,14 @@ pub fn goto(_input: TokenStream) -> TokenStream {
7980
}
8081
.into()
8182
}
83+
84+
// #[derive(ByteRepr)]
85+
// pub struct S;
86+
//
87+
// Adds ByteRepr implementation for S. Currently only empty structs are handled. Non-empty structs
88+
// panic.
89+
90+
#[proc_macro_derive(ByteRepr)]
91+
pub fn derive_byte_repr(input: TokenStream) -> TokenStream {
92+
byte_repr::expand(input)
93+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use libcc2rs_macros::ByteRepr;
2+
3+
#[derive(ByteRepr)]
4+
struct NonEmpty {
5+
x: i32,
6+
}
7+
8+
fn main() {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
error: proc-macro derive panicked
2+
--> tests/ui/byte_repr_non_empty.rs:3:10
3+
|
4+
3 | #[derive(ByteRepr)]
5+
| ^^^^^^^^
6+
|
7+
= help: message: derive(ByteRepr) is only supported on empty structs, `NonEmpty` is not empty

‎libcc2rs/src/lib.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@ pub use fd::*;
5151
mod format;
5252
pub use format::*;
5353

54-
pub use libcc2rs_macros::{goto, goto_block, switch};
54+
pub use libcc2rs_macros::{ByteRepr, goto, goto_block, switch};

‎tests/multi-file/opaque_forward_decl/out/refcount/opaque_forward_decl.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,5 @@ pub fn touch_0(c: Ptr<container>) {
5151
let c: Value<Ptr<container>> = Rc::new(RefCell::new(c));
5252
&(*(*(*c.borrow()).upgrade().deref()).p.borrow());
5353
}
54+
#[derive(Clone, Copy, Default, ByteRepr)]
5455
pub struct opaque;

‎tests/multi-file/opaque_forward_decl/out/unsafe/opaque_forward_decl.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,5 @@ unsafe fn main_0() -> i32 {
3030
pub unsafe fn touch_0(mut c: *mut container) {
3131
&((*c).p);
3232
}
33+
#[derive(Clone, Copy, Default, ByteRepr)]
3334
pub struct opaque;

‎tests/unit/out/refcount/opaque_forward_decl.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,5 @@ fn main_0() -> i32 {
4545
&(*(*c.borrow()).p.borrow());
4646
return ((*(*c.borrow()).x.borrow()) - 42);
4747
}
48+
#[derive(Clone, Copy, Default, ByteRepr)]
4849
pub struct opaque;

‎tests/unit/out/unsafe/opaque_forward_decl.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ unsafe fn main_0() -> i32 {
2525
&(c.p);
2626
return ((c.x) - (42));
2727
}
28+
#[derive(Clone, Copy, Default, ByteRepr)]
2829
pub struct opaque;

0 commit comments

Comments
 (0)