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
82 changes: 23 additions & 59 deletions cpp2rust/converter/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2070,25 +2070,24 @@ bool Converter::VisitCXXBoolLiteralExpr(clang::CXXBoolLiteralExpr *expr) {

void Converter::ConvertIntegerToEnumeralCast(clang::Expr *to,
clang::Expr *from) {
// Short circuit `Enum::from(X as i32)` to `X`
// Short circuit `(X as i32) as Enum` to `X`
if (auto ref =
clang::dyn_cast<clang::DeclRefExpr>(from->IgnoreParenImpCasts())) {
if (auto ec = clang::dyn_cast<clang::EnumConstantDecl>(ref->getDecl())) {
auto src_enum = clang::dyn_cast<clang::EnumDecl>(ec->getDeclContext());
auto dst_enum = to->getType()->getAs<clang::EnumType>();
if (src_enum && dst_enum && dst_enum->getDecl() == src_enum) {
StrCat(std::format("{}::{}", GetRecordName(src_enum),
std::string_view(ec->getName())));
StrCat(EnumeratorName(ec));
return;
}
}
}
StrCat(GetUnsafeTypeAsString(to->getType()), "::from");
PushParen paren(*this);
Convert(from);
if (!from->getType()->isSpecificBuiltinType(clang::BuiltinType::Int)) {
StrCat(keyword::kAs, "i32");
{
PushParen inner(*this);
Convert(from);
}
StrCat(keyword::kAs, GetUnsafeTypeAsString(to->getType()));
}

void Converter::ConvertIntegralToBooleanCast(clang::ImplicitCastExpr *expr) {
Expand All @@ -2107,11 +2106,7 @@ void Converter::ConvertIntegralToBooleanCast(clang::ImplicitCastExpr *expr) {
PushParen paren(*this);
Convert(sub_expr);
StrCat(token::kDiff);
if (sub_expr->getType()->isEnumeralType()) {
StrCat(GetUnsafeTypeAsString(sub_expr->getType()), "::from(0)");
} else /* sub_expr->getType()->isIntegerType() */ {
StrCat(token::kZero);
}
StrCat(token::kZero);
}

bool Converter::IsCastRedundantInRust(clang::Expr *expr,
Expand Down Expand Up @@ -2657,14 +2652,11 @@ std::string Converter::ConvertDeclRefExpr(clang::DeclRefExpr *expr) {
}

if (auto enum_constant = clang::dyn_cast<clang::EnumConstantDecl>(decl)) {
auto qualified = std::format("{}::{}",
GetRecordName(clang::dyn_cast<clang::EnumDecl>(
enum_constant->getDeclContext())),
std::string_view(enum_constant->getName()));
auto name = EnumeratorName(enum_constant);
if (!expr->getType()->isEnumeralType()) {
return std::format("({} as i32)", qualified);
return std::format("({} as i32)", name);
}
return qualified;
return name;
}

if (IsGlobalVar(expr)) {
Expand Down Expand Up @@ -3237,50 +3229,23 @@ bool Converter::VisitEnumDecl(clang::EnumDecl *decl) {
return false;
}
Mapper::AddRuleForUserDefinedType(decl);
Mapper::SetDerives(ctx_.getCanonicalTagType(decl),
{"Clone", "Copy", "PartialEq", "Debug", "Default"});
StrCat("#[derive(Clone, Copy, PartialEq, Debug, Default)]");
StrCat(std::format("enum {}", GetRecordName(decl)));
StrCat('{');
bool first_enumerator = true;
auto name = GetRecordName(decl);
StrCat(std::format("pub type {} = {};", name,
GetUnsafeTypeAsString(decl->getIntegerType())));
for (auto e : decl->enumerators()) {
llvm::SmallVector<char, 32> init;
e->getInitVal().toString(init, 10);
if (first_enumerator) {
StrCat("#[default]");
first_enumerator = false;
}
StrCat(std::format("{} = {},", std::string_view(e->getName()),
StrCat(std::format("pub const {}: {} = {};", EnumeratorName(e), name,
std::string_view(init.data(), init.size())));
}
StrCat('}');

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

void Converter::AddFromImpl(clang::EnumDecl *decl) {
auto name = GetRecordName(decl);
StrCat(std::format("impl From<i32> for {}", name));
PushBrace impl(*this);
StrCat(std::format("fn from(n: i32) -> {}", name));
PushBrace fn(*this);
StrCat("match n");
PushBrace match(*this);
for (auto e : decl->enumerators()) {
llvm::SmallVector<char, 32> init;
e->getInitVal().toString(init, 10);
StrCat(std::format("{} => {}::{},",
std::string_view(init.data(), init.size()), name,
std::string_view(e->getName())));
}
StrCat(std::format("_ => panic!(\"invalid {} value: {{}}\", n),", name));
}

void Converter::AddIncDecImpls(clang::EnumDecl *decl) {
StrCat(std::format("libcc2rs::impl_enum_inc_dec!({});", GetRecordName(decl)));
std::string
Converter::EnumeratorName(const clang::EnumConstantDecl *decl) const {
auto *enum_decl = clang::cast<clang::EnumDecl>(decl->getDeclContext());
return std::format("{}_{}", GetRecordName(enum_decl),
std::string_view(decl->getName()));
}

bool Converter::VisitCXXDefaultArgExpr(clang::CXXDefaultArgExpr *expr) {
Expand Down Expand Up @@ -3570,9 +3535,10 @@ std::string Converter::GetDefaultAsStringFallback(clang::QualType qual_type) {

if (qual_type->isEnumeralType()) {
auto enum_decl = qual_type->castAs<clang::EnumType>()->getDecl();
return std::format(
"{}::{}", GetRecordName(enum_decl),
std::string_view(enum_decl->enumerator_begin()->getName()));
if (enum_decl->enumerators().empty()) {
return std::string(1, token::kZero);
}
return EnumeratorName(*enum_decl->enumerator_begin());
}

return std::format("<{}>::default()", ToString(qual_type));
Expand Down Expand Up @@ -4049,8 +4015,6 @@ 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
6 changes: 1 addition & 5 deletions cpp2rust/converter/converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,9 +374,7 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {

virtual bool VisitEnumDecl(clang::EnumDecl *decl);

virtual void AddFromImpl(clang::EnumDecl *decl);

virtual void AddIncDecImpls(clang::EnumDecl *decl);
virtual std::string EnumeratorName(const clang::EnumConstantDecl *decl) const;

virtual bool VisitCXXDefaultArgExpr(clang::CXXDefaultArgExpr *expr);

Expand Down Expand Up @@ -560,8 +558,6 @@ 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
11 changes: 0 additions & 11 deletions cpp2rust/converter/models/converter_refcount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -654,17 +654,6 @@ 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: 0 additions & 2 deletions cpp2rust/converter/models/converter_refcount.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ class ConverterRefCount final : public Converter {

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

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

bool
VisitUnaryExprOrTypeTraitExpr(clang::UnaryExprOrTypeTraitExpr *expr) override;

Expand Down
32 changes: 0 additions & 32 deletions libcc2rs/src/inc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,38 +124,6 @@ impl<T> UnsafePrefixInc for *mut T {
}
}

#[macro_export]
macro_rules! impl_enum_inc_dec {
($t:ty) => {
impl PostfixInc for $t {
fn postfix_inc(&mut self) -> Self {
let copy = *self;
*self = <$t>::from((*self as i32).wrapping_add(1));
copy
}
}
impl PrefixInc for $t {
fn prefix_inc(&mut self) -> Self {
*self = <$t>::from((*self as i32).wrapping_add(1));
*self
}
}
impl PostfixDec for $t {
fn postfix_dec(&mut self) -> Self {
let copy = *self;
*self = <$t>::from((*self as i32).wrapping_sub(1));
copy
}
}
impl PrefixDec for $t {
fn prefix_dec(&mut self) -> Self {
*self = <$t>::from((*self as i32).wrapping_sub(1));
*self
}
}
};
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,11 @@ use std::io::prelude::*;
use std::io::{Read, Seek, Write};
use std::os::fd::AsFd;
use std::rc::{Rc, Weak};
#[derive(Clone, Copy, PartialEq, Debug, Default)]
enum anon_0 {
#[default]
ALPHA = 7,
}
impl From<i32> for anon_0 {
fn from(n: i32) -> anon_0 {
match n {
7 => anon_0::ALPHA,
_ => panic!("invalid anon_0 value: {}", n),
}
}
}
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 type anon_0 = u32;
pub const anon_0_ALPHA: anon_0 = 7;
pub fn a_value_1() -> i32 {
let x: Value<i32> = Rc::new(RefCell::new(0));
(*x.borrow_mut()) |= (anon_0::ALPHA as i32);
(*x.borrow_mut()) |= (anon_0_ALPHA as i32);
return (*x.borrow());
}
pub fn main() {
Expand All @@ -41,30 +21,10 @@ fn main_0() -> i32 {
assert!((((({ b_value_2() }) == 9) as i32) != 0));
return 0;
}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
enum anon_3 {
#[default]
BETA = 9,
}
impl From<i32> for anon_3 {
fn from(n: i32) -> anon_3 {
match n {
9 => anon_3::BETA,
_ => panic!("invalid anon_3 value: {}", n),
}
}
}
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 type anon_3 = u32;
pub const anon_3_BETA: anon_3 = 9;
pub fn b_value_2() -> i32 {
let x: Value<i32> = Rc::new(RefCell::new(0));
(*x.borrow_mut()) |= (anon_3::BETA as i32);
(*x.borrow_mut()) |= (anon_3_BETA as i32);
return (*x.borrow());
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,11 @@ use std::collections::BTreeMap;
use std::io::{Read, Seek, Write};
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
use std::rc::Rc;
#[derive(Clone, Copy, PartialEq, Debug, Default)]
enum anon_0 {
#[default]
ALPHA = 7,
}
impl From<i32> for anon_0 {
fn from(n: i32) -> anon_0 {
match n {
7 => anon_0::ALPHA,
_ => panic!("invalid anon_0 value: {}", n),
}
}
}
libcc2rs::impl_enum_inc_dec!(anon_0);
pub type anon_0 = u32;
pub const anon_0_ALPHA: anon_0 = 7;
pub unsafe fn a_value_1() -> i32 {
let mut x: i32 = 0;
x |= (anon_0::ALPHA as i32);
x |= (anon_0_ALPHA as i32);
return x;
}
pub fn main() {
Expand All @@ -35,22 +23,10 @@ unsafe fn main_0() -> i32 {
assert!(((((unsafe { b_value_2() }) == (9)) as i32) != 0));
return 0;
}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
enum anon_3 {
#[default]
BETA = 9,
}
impl From<i32> for anon_3 {
fn from(n: i32) -> anon_3 {
match n {
9 => anon_3::BETA,
_ => panic!("invalid anon_3 value: {}", n),
}
}
}
libcc2rs::impl_enum_inc_dec!(anon_3);
pub type anon_3 = u32;
pub const anon_3_BETA: anon_3 = 9;
pub unsafe fn b_value_2() -> i32 {
let mut x: i32 = 0;
x |= (anon_3::BETA as i32);
x |= (anon_3_BETA as i32);
return x;
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,33 +43,11 @@ fn main_0() -> i32 {
assert!((((({ b_value_1() }) == 2) as i32) != 0));
return 0;
}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
enum widget_enum {
#[default]
WIDGET_A = 0,
WIDGET_B = 1,
WIDGET_C = 2,
}
impl From<i32> for widget_enum {
fn from(n: i32) -> widget_enum {
match n {
0 => widget_enum::WIDGET_A,
1 => widget_enum::WIDGET_B,
2 => widget_enum::WIDGET_C,
_ => panic!("invalid widget_enum value: {}", n),
}
}
}
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 type widget_enum = u32;
pub const widget_enum_WIDGET_A: widget_enum = 0;
pub const widget_enum_WIDGET_B: widget_enum = 1;
pub const widget_enum_WIDGET_C: widget_enum = 2;
pub fn b_value_1() -> i32 {
let w: Value<widget_enum> = Rc::new(RefCell::new(widget_enum::WIDGET_C));
let w: Value<widget_enum> = Rc::new(RefCell::new(widget_enum_WIDGET_C));
return ((*w.borrow()) as i32);
}
Loading
Loading