Skip to content

Commit 18a5c4a

Browse files
committed
Translate enums as integres
1 parent 5c99fd1 commit 18a5c4a

5 files changed

Lines changed: 24 additions & 107 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 23 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2070,25 +2070,24 @@ bool Converter::VisitCXXBoolLiteralExpr(clang::CXXBoolLiteralExpr *expr) {
20702070

20712071
void Converter::ConvertIntegerToEnumeralCast(clang::Expr *to,
20722072
clang::Expr *from) {
2073-
// Short circuit `Enum::from(X as i32)` to `X`
2073+
// Short circuit `(X as i32) as Enum` to `X`
20742074
if (auto ref =
20752075
clang::dyn_cast<clang::DeclRefExpr>(from->IgnoreParenImpCasts())) {
20762076
if (auto ec = clang::dyn_cast<clang::EnumConstantDecl>(ref->getDecl())) {
20772077
auto src_enum = clang::dyn_cast<clang::EnumDecl>(ec->getDeclContext());
20782078
auto dst_enum = to->getType()->getAs<clang::EnumType>();
20792079
if (src_enum && dst_enum && dst_enum->getDecl() == src_enum) {
2080-
StrCat(std::format("{}::{}", GetRecordName(src_enum),
2081-
std::string_view(ec->getName())));
2080+
StrCat(EnumeratorName(ec));
20822081
return;
20832082
}
20842083
}
20852084
}
2086-
StrCat(GetUnsafeTypeAsString(to->getType()), "::from");
20872085
PushParen paren(*this);
2088-
Convert(from);
2089-
if (!from->getType()->isSpecificBuiltinType(clang::BuiltinType::Int)) {
2090-
StrCat(keyword::kAs, "i32");
2086+
{
2087+
PushParen inner(*this);
2088+
Convert(from);
20912089
}
2090+
StrCat(keyword::kAs, GetUnsafeTypeAsString(to->getType()));
20922091
}
20932092

20942093
void Converter::ConvertIntegralToBooleanCast(clang::ImplicitCastExpr *expr) {
@@ -2107,11 +2106,7 @@ void Converter::ConvertIntegralToBooleanCast(clang::ImplicitCastExpr *expr) {
21072106
PushParen paren(*this);
21082107
Convert(sub_expr);
21092108
StrCat(token::kDiff);
2110-
if (sub_expr->getType()->isEnumeralType()) {
2111-
StrCat(GetUnsafeTypeAsString(sub_expr->getType()), "::from(0)");
2112-
} else /* sub_expr->getType()->isIntegerType() */ {
2113-
StrCat(token::kZero);
2114-
}
2109+
StrCat(token::kZero);
21152110
}
21162111

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

26592654
if (auto enum_constant = clang::dyn_cast<clang::EnumConstantDecl>(decl)) {
2660-
auto qualified = std::format("{}::{}",
2661-
GetRecordName(clang::dyn_cast<clang::EnumDecl>(
2662-
enum_constant->getDeclContext())),
2663-
std::string_view(enum_constant->getName()));
2655+
auto name = EnumeratorName(enum_constant);
26642656
if (!expr->getType()->isEnumeralType()) {
2665-
return std::format("({} as i32)", qualified);
2657+
return std::format("({} as i32)", name);
26662658
}
2667-
return qualified;
2659+
return name;
26682660
}
26692661

26702662
if (IsGlobalVar(expr)) {
@@ -3237,50 +3229,23 @@ bool Converter::VisitEnumDecl(clang::EnumDecl *decl) {
32373229
return false;
32383230
}
32393231
Mapper::AddRuleForUserDefinedType(decl);
3240-
Mapper::SetDerives(ctx_.getCanonicalTagType(decl),
3241-
{"Clone", "Copy", "PartialEq", "Debug", "Default"});
3242-
StrCat("#[derive(Clone, Copy, PartialEq, Debug, Default)]");
3243-
StrCat(std::format("enum {}", GetRecordName(decl)));
3244-
StrCat('{');
3245-
bool first_enumerator = true;
3232+
auto name = GetRecordName(decl);
3233+
StrCat(std::format("pub type {} = {};", name,
3234+
GetUnsafeTypeAsString(decl->getIntegerType())));
32463235
for (auto e : decl->enumerators()) {
32473236
llvm::SmallVector<char, 32> init;
32483237
e->getInitVal().toString(init, 10);
3249-
if (first_enumerator) {
3250-
StrCat("#[default]");
3251-
first_enumerator = false;
3252-
}
3253-
StrCat(std::format("{} = {},", std::string_view(e->getName()),
3238+
StrCat(std::format("pub const {}: {} = {};", EnumeratorName(e), name,
32543239
std::string_view(init.data(), init.size())));
32553240
}
3256-
StrCat('}');
3257-
3258-
AddFromImpl(decl);
3259-
AddIncDecImpls(decl);
3260-
AddByteReprTrait(decl);
32613241
return false;
32623242
}
32633243

3264-
void Converter::AddFromImpl(clang::EnumDecl *decl) {
3265-
auto name = GetRecordName(decl);
3266-
StrCat(std::format("impl From<i32> for {}", name));
3267-
PushBrace impl(*this);
3268-
StrCat(std::format("fn from(n: i32) -> {}", name));
3269-
PushBrace fn(*this);
3270-
StrCat("match n");
3271-
PushBrace match(*this);
3272-
for (auto e : decl->enumerators()) {
3273-
llvm::SmallVector<char, 32> init;
3274-
e->getInitVal().toString(init, 10);
3275-
StrCat(std::format("{} => {}::{},",
3276-
std::string_view(init.data(), init.size()), name,
3277-
std::string_view(e->getName())));
3278-
}
3279-
StrCat(std::format("_ => panic!(\"invalid {} value: {{}}\", n),", name));
3280-
}
3281-
3282-
void Converter::AddIncDecImpls(clang::EnumDecl *decl) {
3283-
StrCat(std::format("libcc2rs::impl_enum_inc_dec!({});", GetRecordName(decl)));
3244+
std::string
3245+
Converter::EnumeratorName(const clang::EnumConstantDecl *decl) const {
3246+
auto *enum_decl = clang::cast<clang::EnumDecl>(decl->getDeclContext());
3247+
return std::format("{}_{}", GetRecordName(enum_decl),
3248+
std::string_view(decl->getName()));
32843249
}
32853250

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

35713536
if (qual_type->isEnumeralType()) {
35723537
auto enum_decl = qual_type->castAs<clang::EnumType>()->getDecl();
3573-
return std::format(
3574-
"{}::{}", GetRecordName(enum_decl),
3575-
std::string_view(enum_decl->enumerator_begin()->getName()));
3538+
if (enum_decl->enumerators().empty()) {
3539+
return std::string(1, token::kZero);
3540+
}
3541+
return EnumeratorName(*enum_decl->enumerator_begin());
35763542
}
35773543

35783544
return std::format("<{}>::default()", ToString(qual_type));
@@ -4049,8 +4015,6 @@ void Converter::EmitDefaultStructLiteral(const clang::RecordDecl *decl) {
40494015

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

4052-
void Converter::AddByteReprTrait(const clang::EnumDecl *decl) {}
4053-
40544018
void Converter::ConvertUnsignedArithBinaryOperator(clang::BinaryOperator *op,
40554019
clang::Expr *expr) {
40564020
StrCat(token::kDot);

‎cpp2rust/converter/converter.h‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,7 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
374374

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

377-
virtual void AddFromImpl(clang::EnumDecl *decl);
378-
379-
virtual void AddIncDecImpls(clang::EnumDecl *decl);
377+
virtual std::string EnumeratorName(const clang::EnumConstantDecl *decl) const;
380378

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

@@ -560,7 +558,6 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
560558

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

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

565562
virtual void
566563
ConvertUnsignedArithBinaryOperator(clang::BinaryOperator *binary_operator,

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -654,17 +654,6 @@ void ConverterRefCount::AddByteReprTrait(const clang::RecordDecl *decl) {
654654
}
655655
}
656656

657-
void ConverterRefCount::AddByteReprTrait(const clang::EnumDecl *decl) {
658-
auto name = GetRecordName(decl);
659-
StrCat(std::format("impl ByteRepr for {}", name));
660-
PushBrace impl_brace(*this);
661-
StrCat(
662-
"fn to_bytes(&self, buf: &mut [u8]) { (*self as i32).to_bytes(buf); }");
663-
StrCat(std::format("fn from_bytes(buf: &[u8]) -> Self {{ "
664-
"<{}>::from(i32::from_bytes(buf)) }}",
665-
name));
666-
}
667-
668657
std::string
669658
ConverterRefCount::GetSelfMaybeWithMut(const clang::CXXMethodDecl *decl) {
670659
return "&self";

‎cpp2rust/converter/models/converter_refcount.h‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ class ConverterRefCount final : public Converter {
4545

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

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

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

‎libcc2rs/src/inc.rs‎

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -124,38 +124,6 @@ impl<T> UnsafePrefixInc for *mut T {
124124
}
125125
}
126126

127-
#[macro_export]
128-
macro_rules! impl_enum_inc_dec {
129-
($t:ty) => {
130-
impl PostfixInc for $t {
131-
fn postfix_inc(&mut self) -> Self {
132-
let copy = *self;
133-
*self = <$t>::from((*self as i32).wrapping_add(1));
134-
copy
135-
}
136-
}
137-
impl PrefixInc for $t {
138-
fn prefix_inc(&mut self) -> Self {
139-
*self = <$t>::from((*self as i32).wrapping_add(1));
140-
*self
141-
}
142-
}
143-
impl PostfixDec for $t {
144-
fn postfix_dec(&mut self) -> Self {
145-
let copy = *self;
146-
*self = <$t>::from((*self as i32).wrapping_sub(1));
147-
copy
148-
}
149-
}
150-
impl PrefixDec for $t {
151-
fn prefix_dec(&mut self) -> Self {
152-
*self = <$t>::from((*self as i32).wrapping_sub(1));
153-
*self
154-
}
155-
}
156-
};
157-
}
158-
159127
#[cfg(test)]
160128
mod tests {
161129
use super::*;

0 commit comments

Comments
 (0)