Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cpp2rust/converter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3154,6 +3154,7 @@ bool Converter::VisitEnumDecl(clang::EnumDecl *decl) {

AddFromImpl(decl);
AddIncDecImpls(decl);
AddByteReprTrait(decl);
return false;
}

Expand Down Expand Up @@ -3936,6 +3937,8 @@ void Converter::EmitDefaultStructLiteral(const clang::RecordDecl *decl) {

void Converter::AddByteReprTrait(const clang::RecordDecl *decl) {}

void Converter::AddByteReprTrait(const clang::EnumDecl *decl) {}

void Converter::ConvertUnsignedArithBinaryOperator(clang::BinaryOperator *op,
clang::Expr *expr) {
StrCat(token::kDot);
Expand Down
2 changes: 2 additions & 0 deletions cpp2rust/converter/converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,8 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {

virtual void AddByteReprTrait(const clang::RecordDecl *decl);

virtual void AddByteReprTrait(const clang::EnumDecl *decl);

virtual void
ConvertUnsignedArithBinaryOperator(clang::BinaryOperator *binary_operator,
clang::Expr *expr);
Expand Down
17 changes: 13 additions & 4 deletions cpp2rust/converter/models/converter_refcount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,10 +510,8 @@ static bool recordImplementsByteRepr(const clang::RecordDecl *decl) {
// fields.
for (auto *f : decl->fields()) {
auto qt = f->getType();
if (qt->isEnumeralType()) {
return false;
}
if (!qt->isIntegerType() && !qt->isFloatingType()) {
if (!qt->isIntegerType() && !qt->isFloatingType() &&
!qt->isEnumeralType()) {
return false;
}
}
Expand Down Expand Up @@ -567,6 +565,17 @@ void ConverterRefCount::AddByteReprTrait(const clang::RecordDecl *decl) {
}
}

void ConverterRefCount::AddByteReprTrait(const clang::EnumDecl *decl) {
auto name = GetRecordName(decl);
StrCat(std::format("impl ByteRepr for {}", name));
PushBrace impl_brace(*this);
StrCat(
"fn to_bytes(&self, buf: &mut [u8]) { (*self as i32).to_bytes(buf); }");
StrCat(std::format("fn from_bytes(buf: &[u8]) -> Self {{ "
"<{}>::from(i32::from_bytes(buf)) }}",
name));
}

std::string
ConverterRefCount::GetSelfMaybeWithMut(const clang::CXXMethodDecl *decl) {
return "&self";
Expand Down
2 changes: 2 additions & 0 deletions cpp2rust/converter/models/converter_refcount.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ class ConverterRefCount final : public Converter {

void AddByteReprTrait(const clang::RecordDecl *decl) override;

void AddByteReprTrait(const clang::EnumDecl *decl) override;

void AddDefaultTrait(const clang::RecordDecl *decl) override;

void AddDefaultTraitForUnion(const clang::RecordDecl *decl) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ impl From<i32> for anon_0 {
}
}
libcc2rs::impl_enum_inc_dec!(anon_0);
impl ByteRepr for anon_0 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<anon_0>::from(i32::from_bytes(buf))
}
}
pub fn a_value_1() -> i32 {
let x: Value<i32> = Rc::new(RefCell::new(0));
(*x.borrow_mut()) |= (anon_0::ALPHA as i32);
Expand Down Expand Up @@ -47,6 +55,14 @@ impl From<i32> for anon_3 {
}
}
libcc2rs::impl_enum_inc_dec!(anon_3);
impl ByteRepr for anon_3 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<anon_3>::from(i32::from_bytes(buf))
}
}
pub fn b_value_2() -> i32 {
let x: Value<i32> = Rc::new(RefCell::new(0));
(*x.borrow_mut()) |= (anon_3::BETA as i32);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ impl From<i32> for widget_enum {
}
}
libcc2rs::impl_enum_inc_dec!(widget_enum);
impl ByteRepr for widget_enum {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<widget_enum>::from(i32::from_bytes(buf))
}
}
pub fn b_value_1() -> i32 {
let w: Value<widget_enum> = Rc::new(RefCell::new(widget_enum::WIDGET_C));
return ((*w.borrow()) as i32).clone();
Expand Down
8 changes: 8 additions & 0 deletions tests/ub/out/refcount/enum_out_of_range_cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ impl From<i32> for Color {
}
}
libcc2rs::impl_enum_inc_dec!(Color);
impl ByteRepr for Color {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<Color>::from(i32::from_bytes(buf))
}
}
pub fn main() {
std::process::exit(main_0());
}
Expand Down
8 changes: 8 additions & 0 deletions tests/ub/out/refcount/enum_out_of_range_increment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ impl From<i32> for color {
}
}
libcc2rs::impl_enum_inc_dec!(color);
impl ByteRepr for color {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<color>::from(i32::from_bytes(buf))
}
}
pub fn main() {
std::process::exit(main_0());
}
Expand Down
53 changes: 52 additions & 1 deletion tests/unit/out/refcount/anonymous_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ impl From<i32> for anon_0 {
}
}
libcc2rs::impl_enum_inc_dec!(anon_0);
impl ByteRepr for anon_0 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<anon_0>::from(i32::from_bytes(buf))
}
}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
enum anon_1 {
#[default]
Expand All @@ -38,6 +46,14 @@ impl From<i32> for anon_1 {
}
}
libcc2rs::impl_enum_inc_dec!(anon_1);
impl ByteRepr for anon_1 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<anon_1>::from(i32::from_bytes(buf))
}
}
#[derive(Default)]
pub struct S {
pub a: Value<i32>,
Expand Down Expand Up @@ -76,6 +92,14 @@ impl From<i32> for TdEnum {
}
}
libcc2rs::impl_enum_inc_dec!(TdEnum);
impl ByteRepr for TdEnum {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<TdEnum>::from(i32::from_bytes(buf))
}
}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
enum anon_2 {
#[default]
Expand All @@ -92,6 +116,14 @@ impl From<i32> for anon_2 {
}
}
libcc2rs::impl_enum_inc_dec!(anon_2);
impl ByteRepr for anon_2 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<anon_2>::from(i32::from_bytes(buf))
}
}
#[derive(Default)]
pub struct WithAnonField {
pub a: Value<i32>,
Expand All @@ -106,7 +138,18 @@ impl Clone for WithAnonField {
this
}
}
impl ByteRepr for WithAnonField {}
impl ByteRepr for WithAnonField {
fn to_bytes(&self, buf: &mut [u8]) {
(*self.a.borrow()).to_bytes(&mut buf[0..4]);
(*self.field.borrow()).to_bytes(&mut buf[4..8]);
}
fn from_bytes(buf: &[u8]) -> Self {
Self {
a: Rc::new(RefCell::new(<i32>::from_bytes(&buf[0..4]))),
field: Rc::new(RefCell::new(<anon_2>::from_bytes(&buf[4..8]))),
}
}
}
pub fn main() {
std::process::exit(main_0());
}
Expand All @@ -127,6 +170,14 @@ fn main_0() -> i32 {
}
}
libcc2rs::impl_enum_inc_dec!(anon_3);
impl ByteRepr for anon_3 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<anon_3>::from(i32::from_bytes(buf))
}
};
assert!(((anon_0::FIRST_A as i32) != (anon_0::FIRST_B as i32)));
assert!(((anon_1::SECOND_A as i32) != (anon_1::SECOND_B as i32)));
assert!(((anon_3::THIRD_A as i32) != (anon_3::THIRD_B as i32)));
Expand Down
53 changes: 52 additions & 1 deletion tests/unit/out/refcount/anonymous_enum_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ impl From<i32> for anon_0 {
}
}
libcc2rs::impl_enum_inc_dec!(anon_0);
impl ByteRepr for anon_0 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<anon_0>::from(i32::from_bytes(buf))
}
}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
enum anon_1 {
#[default]
Expand All @@ -38,6 +46,14 @@ impl From<i32> for anon_1 {
}
}
libcc2rs::impl_enum_inc_dec!(anon_1);
impl ByteRepr for anon_1 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<anon_1>::from(i32::from_bytes(buf))
}
}
#[derive(Default)]
pub struct S {
pub a: Value<i32>,
Expand Down Expand Up @@ -68,6 +84,14 @@ impl From<i32> for TdEnum_enum {
}
}
libcc2rs::impl_enum_inc_dec!(TdEnum_enum);
impl ByteRepr for TdEnum_enum {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<TdEnum_enum>::from(i32::from_bytes(buf))
}
}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
enum anon_2 {
#[default]
Expand All @@ -84,12 +108,31 @@ impl From<i32> for anon_2 {
}
}
libcc2rs::impl_enum_inc_dec!(anon_2);
impl ByteRepr for anon_2 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<anon_2>::from(i32::from_bytes(buf))
}
}
#[derive(Default)]
pub struct WithAnonField {
pub a: Value<i32>,
pub field: Value<anon_2>,
}
impl ByteRepr for WithAnonField {}
impl ByteRepr for WithAnonField {
fn to_bytes(&self, buf: &mut [u8]) {
(*self.a.borrow()).to_bytes(&mut buf[0..4]);
(*self.field.borrow()).to_bytes(&mut buf[4..8]);
}
fn from_bytes(buf: &[u8]) -> Self {
Self {
a: Rc::new(RefCell::new(<i32>::from_bytes(&buf[0..4]))),
field: Rc::new(RefCell::new(<anon_2>::from_bytes(&buf[4..8]))),
}
}
}
pub fn main() {
std::process::exit(main_0());
}
Expand All @@ -110,6 +153,14 @@ fn main_0() -> i32 {
}
}
libcc2rs::impl_enum_inc_dec!(anon_3);
impl ByteRepr for anon_3 {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<anon_3>::from(i32::from_bytes(buf))
}
};
assert!(((((anon_0::FIRST_A as i32) != (anon_0::FIRST_B as i32)) as i32) != 0));
assert!(((((anon_1::SECOND_A as i32) != (anon_1::SECOND_B as i32)) as i32) != 0));
assert!(((((anon_3::THIRD_A as i32) != (anon_3::THIRD_B as i32)) as i32) != 0));
Expand Down
8 changes: 8 additions & 0 deletions tests/unit/out/refcount/bool_condition_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ impl From<i32> for Code {
}
}
libcc2rs::impl_enum_inc_dec!(Code);
impl ByteRepr for Code {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<Code>::from(i32::from_bytes(buf))
}
}
pub fn main() {
std::process::exit(main_0());
}
Expand Down
8 changes: 8 additions & 0 deletions tests/unit/out/refcount/bool_condition_enum_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ impl From<i32> for Code {
}
}
libcc2rs::impl_enum_inc_dec!(Code);
impl ByteRepr for Code {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<Code>::from(i32::from_bytes(buf))
}
}
pub fn main() {
std::process::exit(main_0());
}
Expand Down
8 changes: 8 additions & 0 deletions tests/unit/out/refcount/bool_condition_logical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ impl From<i32> for Code {
}
}
libcc2rs::impl_enum_inc_dec!(Code);
impl ByteRepr for Code {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<Code>::from(i32::from_bytes(buf))
}
}
thread_local!(
pub static side_effect_0: Value<i32> = Rc::new(RefCell::new(0));
);
Expand Down
8 changes: 8 additions & 0 deletions tests/unit/out/refcount/bool_condition_logical_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ impl From<i32> for Code {
}
}
libcc2rs::impl_enum_inc_dec!(Code);
impl ByteRepr for Code {
fn to_bytes(&self, buf: &mut [u8]) {
(*self as i32).to_bytes(buf);
}
fn from_bytes(buf: &[u8]) -> Self {
<Code>::from(i32::from_bytes(buf))
}
}
thread_local!(
pub static side_effect_0: Value<i32> = Rc::new(RefCell::new(0));
);
Expand Down
Loading
Loading