diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index 83ebc988..845cf3ad 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -4,6 +4,7 @@ #include "converter/mapper.h" #include +#include #include #include #include @@ -922,8 +923,30 @@ std::string ToString(const clang::NamedDecl *decl) { } os << ToString(func_decl->getReturnType()) << ' '; - if (const auto *method_decl = - llvm::dyn_cast(func_decl)) { + if (const auto op = func_decl->getOverloadedOperator(); + op >= clang::OverloadedOperatorKind::OO_LessLess && + op <= clang::OverloadedOperatorKind::OO_GreaterGreaterEqual) { + // ensure matchTemplate does not consider these operator names when matching + func_decl->getQualifier().print(os, getPrintPolicy()); + os << "operator "; + switch (op) { + case clang::OverloadedOperatorKind::OO_LessLess: + os << "shl"; + break; + case clang::OverloadedOperatorKind::OO_GreaterGreater: + os << "shr"; + break; + case clang::OverloadedOperatorKind::OO_LessLessEqual: + os << "shleq"; + break; + case clang::OverloadedOperatorKind::OO_GreaterGreaterEqual: + os << "shreq"; + break; + default: + assert(0 && "Unexpected overloaded operator kind"); + } + } else if (const auto *method_decl = + llvm::dyn_cast(func_decl)) { if (method_decl->getParent()->isLambda() && method_decl->getOverloadedOperator() == clang::OO_Call) { func_decl->printName(os, getPrintPolicy()); diff --git a/rules/cstddef/src.cpp b/rules/cstddef/src.cpp new file mode 100644 index 00000000..9ae81ccd --- /dev/null +++ b/rules/cstddef/src.cpp @@ -0,0 +1,14 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +#include + +using t1 = std::byte; + +std::byte f1(const std::byte &a0, unsigned a1) { return operator<<(a0, a1); } + +std::byte f2(const std::byte &a0, unsigned a1) { return operator>>(a0, a1); } + +std::byte f3(std::byte &a0, unsigned a1) { return operator<<=(a0, a1); } + +std::byte f4(std::byte &a0, unsigned a1) { return operator>>=(a0, a1); } diff --git a/rules/cstddef/tgt_unsafe.rs b/rules/cstddef/tgt_unsafe.rs new file mode 100644 index 00000000..d40e1d1c --- /dev/null +++ b/rules/cstddef/tgt_unsafe.rs @@ -0,0 +1,26 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +fn t1() -> u8 { + Default::default() +} + +fn f1(a0: &mut u8, a1: u32) -> u8 { + *a0 << a1 +} + +fn f2(a0: &mut u8, a1: u32) -> u8 { + *a0 >> a1 +} + +fn f3(a0: &mut u8, a1: u32) -> u8 { + let n_ = *a0 << a1; + *a0 = n_; + *a0 +} + +fn f4(a0: &mut u8, a1: u32) -> u8 { + let n_ = *a0 >> a1; + *a0 = n_; + *a0 +} diff --git a/rules/src/modules.rs b/rules/src/modules.rs index f4404a32..efedce2b 100644 --- a/rules/src/modules.rs +++ b/rules/src/modules.rs @@ -28,6 +28,8 @@ pub mod carray_tgt_refcount; pub mod carray_tgt_unsafe; #[path = r#"../cmath/tgt_unsafe.rs"#] pub mod cmath_tgt_unsafe; +#[path = r#"../cstddef/tgt_unsafe.rs"#] +pub mod cstddef_tgt_unsafe; #[path = r#"../cstdlib/tgt_refcount.rs"#] pub mod cstdlib_tgt_refcount; #[path = r#"../cstdlib/tgt_unsafe.rs"#] diff --git a/tests/unit/byte.cpp b/tests/unit/byte.cpp new file mode 100644 index 00000000..9eead968 --- /dev/null +++ b/tests/unit/byte.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +#include +#include + +int main() { + std::byte b1{0x01}; + + unsigned ushift1 = 3; + std::byte shl1 = b1 << ushift1; + assert(shl1 == std::byte(0x08)); + + unsigned ushift2 = 2; + std::byte shr1 = shl1 >> ushift2; + assert(shr1 == std::byte(0x02)); + + unsigned ushift3 = 5; + b1 <<= ushift3; + assert(b1 == std::byte(0x20)); + + unsigned ushift4 = 3; + b1 >>= ushift4; + assert(b1 == std::byte(0x04)); + return 0; +} diff --git a/tests/unit/out/refcount/byte.rs b/tests/unit/out/refcount/byte.rs new file mode 100644 index 00000000..c7b6fbfa --- /dev/null +++ b/tests/unit/out/refcount/byte.rs @@ -0,0 +1,35 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let b1: Value = Rc::new(RefCell::new(1_u8)); + let ushift1: Value = Rc::new(RefCell::new(3_u32)); + let shl1: Value = Rc::new(RefCell::new((*b1.borrow()) << (*ushift1.borrow()))); + assert!(((*shl1.borrow()) == 8)); + let ushift2: Value = Rc::new(RefCell::new(2_u32)); + let shr1: Value = Rc::new(RefCell::new((*shl1.borrow()) >> (*ushift2.borrow()))); + assert!(((*shr1.borrow()) == 2)); + let ushift3: Value = Rc::new(RefCell::new(5_u32)); + { + let n_ = (*b1.borrow()) << (*ushift3.borrow()); + (*b1.borrow_mut()) = n_; + (*b1.borrow()) + }; + assert!(((*b1.borrow()) == 32)); + let ushift4: Value = Rc::new(RefCell::new(3_u32)); + { + let n_ = (*b1.borrow()) >> (*ushift4.borrow()); + (*b1.borrow_mut()) = n_; + (*b1.borrow()) + }; + assert!(((*b1.borrow()) == 4)); + return 0; +} diff --git a/tests/unit/out/unsafe/byte.rs b/tests/unit/out/unsafe/byte.rs new file mode 100644 index 00000000..a48cf14c --- /dev/null +++ b/tests/unit/out/unsafe/byte.rs @@ -0,0 +1,37 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut b1: u8 = 1_u8; + let mut ushift1: u32 = 3_u32; + let mut shl1: u8 = b1 << ushift1; + assert!(((shl1) == (8))); + let mut ushift2: u32 = 2_u32; + let mut shr1: u8 = shl1 >> ushift2; + assert!(((shr1) == (2))); + let mut ushift3: u32 = 5_u32; + { + let n_ = b1 << ushift3; + b1 = n_; + b1 + }; + assert!(((b1) == (32))); + let mut ushift4: u32 = 3_u32; + { + let n_ = b1 >> ushift4; + b1 = n_; + b1 + }; + assert!(((b1) == (4))); + return 0; +}