Skip to content

Commit c2b701f

Browse files
authored
Emit bool values for enums with bool underlying type (#470)
1 parent f7222a2 commit c2b701f

4 files changed

Lines changed: 184 additions & 2 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2482,6 +2482,12 @@ void Converter::ConvertIntegralToBooleanCast(clang::ImplicitCastExpr *expr) {
24822482
auto sub_expr = expr->getSubExpr();
24832483
auto *stripped = sub_expr->IgnoreParenImpCasts();
24842484

2485+
if (auto *enum_type = sub_expr->getType()->getAs<clang::EnumType>();
2486+
enum_type && enum_type->getDecl()->getIntegerType()->isBooleanType()) {
2487+
Convert(sub_expr);
2488+
return;
2489+
}
2490+
24852491
if (auto binop = clang::dyn_cast<clang::BinaryOperator>(stripped)) {
24862492
// Comparisons and logical ops already produces bool, no wrap needed.
24872493
if ((binop->isComparisonOp() || binop->isLogicalOp()) &&
@@ -3847,11 +3853,16 @@ bool Converter::VisitEnumDecl(clang::EnumDecl *decl) {
38473853
auto name = GetRecordName(decl);
38483854
StrCat(std::format("pub type {} = {};", name,
38493855
GetUnsafeTypeAsString(decl->getIntegerType())));
3856+
bool is_bool = decl->getIntegerType()->isBooleanType();
38503857
for (auto e : decl->enumerators()) {
38513858
llvm::SmallVector<char, 32> init;
38523859
e->getInitVal().toString(init, 10);
3853-
StrCat(std::format("pub const {}: {} = {};", EnumeratorName(e), name,
3854-
std::string_view(init.data(), init.size())));
3860+
std::string value(init.data(), init.size());
3861+
if (is_bool) {
3862+
value = e->getInitVal().getBoolValue() ? "true" : "false";
3863+
}
3864+
StrCat(
3865+
std::format("pub const {}: {} = {};", EnumeratorName(e), name, value));
38553866
}
38563867
return false;
38573868
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include <cassert>
2+
#include <cstdint>
3+
4+
enum Flag : bool { FLAG_OFF = false, FLAG_ON = true };
5+
6+
enum Small : unsigned char { SMALL_ZERO = 0, SMALL_MAX = 255 };
7+
8+
enum Signed : signed char { SIGNED_MIN = -128, SIGNED_ONE = 1 };
9+
10+
enum Wide : long long { WIDE_NEG = -1, WIDE_BIG = 1LL << 40 };
11+
12+
enum Sized : uint16_t { SIZED_A = 1, SIZED_B = 0xFFFF };
13+
14+
enum class Scoped : int8_t { NEG = -2, POS = 2 };
15+
16+
int main() {
17+
Flag flag = FLAG_ON;
18+
assert(flag);
19+
assert(!FLAG_OFF);
20+
flag = FLAG_OFF;
21+
assert(flag == FLAG_OFF);
22+
bool b = flag;
23+
assert(b == false);
24+
25+
Small s = SMALL_MAX;
26+
assert(s == 255);
27+
assert(sizeof(s) == 1);
28+
s = SMALL_ZERO;
29+
assert(s + 1 == 1);
30+
31+
Signed sg = SIGNED_MIN;
32+
assert(sg == -128);
33+
assert(sg < SIGNED_ONE);
34+
35+
Wide w = WIDE_BIG;
36+
assert(w == (1LL << 40));
37+
assert(sizeof(w) == 8);
38+
assert(WIDE_NEG < 0);
39+
40+
Sized z = SIZED_B;
41+
assert(z == 0xFFFF);
42+
assert(sizeof(z) == 2);
43+
assert(SIZED_A + 1 == 2);
44+
45+
Scoped sc = Scoped::NEG;
46+
assert(static_cast<int>(sc) == -2);
47+
assert(static_cast<int8_t>(Scoped::POS) == 2);
48+
return 0;
49+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
extern crate libcc2rs;
2+
use libcc2rs::*;
3+
use std::cell::RefCell;
4+
use std::collections::BTreeMap;
5+
use std::io::prelude::*;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::AsFd;
8+
use std::rc::{Rc, Weak};
9+
pub type Flag = bool;
10+
pub const Flag_FLAG_OFF: Flag = false;
11+
pub const Flag_FLAG_ON: Flag = true;
12+
pub type Small = u8;
13+
pub const Small_SMALL_ZERO: Small = 0;
14+
pub const Small_SMALL_MAX: Small = 255;
15+
pub type Signed = i8;
16+
pub const Signed_SIGNED_MIN: Signed = -128;
17+
pub const Signed_SIGNED_ONE: Signed = 1;
18+
pub type Wide = i64;
19+
pub const Wide_WIDE_NEG: Wide = -1;
20+
pub const Wide_WIDE_BIG: Wide = 1099511627776;
21+
pub type Sized = u16;
22+
pub const Sized_SIZED_A: Sized = 1;
23+
pub const Sized_SIZED_B: Sized = 65535;
24+
pub type Scoped = i8;
25+
pub const Scoped_NEG: Scoped = -2;
26+
pub const Scoped_POS: Scoped = 2;
27+
pub fn main() {
28+
__cpp2rust_init_globals();
29+
std::process::exit(main_0());
30+
}
31+
fn main_0() -> i32 {
32+
let mut flag: Flag = Flag_FLAG_ON;
33+
assert!(flag);
34+
assert!(!(Flag_FLAG_OFF));
35+
flag = Flag_FLAG_OFF;
36+
assert!(((flag as i32) == (Flag_FLAG_OFF as i32)));
37+
let mut b: bool = flag;
38+
assert!(((b as i32) == (false as i32)));
39+
let mut s: Small = Small_SMALL_MAX;
40+
assert!(((s as i32) == 255));
41+
assert!((::std::mem::size_of::<Small>() == 1_usize));
42+
s = Small_SMALL_ZERO;
43+
assert!((((s as i32) + 1) == 1));
44+
let mut sg: Signed = Signed_SIGNED_MIN;
45+
assert!(((sg as i32) == -128_i32));
46+
assert!(((sg as i32) < (Signed_SIGNED_ONE as i32)));
47+
let mut w: Wide = Wide_WIDE_BIG;
48+
assert!(((w as i64) == (1_i64 << 40)));
49+
assert!((::std::mem::size_of::<Wide>() == 8_usize));
50+
assert!(((Wide_WIDE_NEG as i64) < 0_i64));
51+
let mut z: Sized = Sized_SIZED_B;
52+
assert!(((z as i32) == 65535));
53+
assert!((::std::mem::size_of::<Sized>() == 2_usize));
54+
assert!((((Sized_SIZED_A as i32) + 1) == 2));
55+
let mut sc: Scoped = Scoped_NEG;
56+
assert!(((sc as i32) == -2_i32));
57+
assert!((((Scoped_POS as i8) as i32) == 2));
58+
return 0;
59+
}
60+
pub fn __cpp2rust_init_globals() {}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
extern crate libc;
2+
use libc::*;
3+
extern crate libcc2rs;
4+
use libcc2rs::*;
5+
use std::collections::BTreeMap;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
8+
use std::rc::Rc;
9+
pub type Flag = bool;
10+
pub const Flag_FLAG_OFF: Flag = false;
11+
pub const Flag_FLAG_ON: Flag = true;
12+
pub type Small = u8;
13+
pub const Small_SMALL_ZERO: Small = 0;
14+
pub const Small_SMALL_MAX: Small = 255;
15+
pub type Signed = i8;
16+
pub const Signed_SIGNED_MIN: Signed = -128;
17+
pub const Signed_SIGNED_ONE: Signed = 1;
18+
pub type Wide = i64;
19+
pub const Wide_WIDE_NEG: Wide = -1;
20+
pub const Wide_WIDE_BIG: Wide = 1099511627776;
21+
pub type Sized = u16;
22+
pub const Sized_SIZED_A: Sized = 1;
23+
pub const Sized_SIZED_B: Sized = 65535;
24+
pub type Scoped = i8;
25+
pub const Scoped_NEG: Scoped = -2;
26+
pub const Scoped_POS: Scoped = 2;
27+
pub fn main() {
28+
unsafe {
29+
__cpp2rust_init_globals();
30+
std::process::exit(main_0() as i32);
31+
}
32+
}
33+
unsafe fn main_0() -> i32 {
34+
let mut flag: Flag = Flag_FLAG_ON;
35+
assert!(flag);
36+
assert!(!(Flag_FLAG_OFF));
37+
flag = Flag_FLAG_OFF;
38+
assert!(((flag as i32) == (Flag_FLAG_OFF as i32)));
39+
let mut b: bool = flag;
40+
assert!(((b as i32) == (false as i32)));
41+
let mut s: Small = Small_SMALL_MAX;
42+
assert!(((s as i32) == (255)));
43+
assert!(((::std::mem::size_of::<Small>()) == (1_usize)));
44+
s = Small_SMALL_ZERO;
45+
assert!((((s as i32) + (1)) == (1)));
46+
let mut sg: Signed = Signed_SIGNED_MIN;
47+
assert!(((sg as i32) == (-128_i32)));
48+
assert!(((sg as i32) < (Signed_SIGNED_ONE as i32)));
49+
let mut w: Wide = Wide_WIDE_BIG;
50+
assert!(((w as i64) == ((1_i64) << (40))));
51+
assert!(((::std::mem::size_of::<Wide>()) == (8_usize)));
52+
assert!(((Wide_WIDE_NEG as i64) < (0_i64)));
53+
let mut z: Sized = Sized_SIZED_B;
54+
assert!(((z as i32) == (65535)));
55+
assert!(((::std::mem::size_of::<Sized>()) == (2_usize)));
56+
assert!((((Sized_SIZED_A as i32) + (1)) == (2)));
57+
let mut sc: Scoped = Scoped_NEG;
58+
assert!(((sc as i32) == (-2_i32)));
59+
assert!((((Scoped_POS as i8) as i32) == (2)));
60+
return 0;
61+
}
62+
pub unsafe fn __cpp2rust_init_globals() {}

0 commit comments

Comments
 (0)