Skip to content

Commit 1bc9b5e

Browse files
committed
Translate wide strings
1 parent 1ed5626 commit 1bc9b5e

5 files changed

Lines changed: 73 additions & 12 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2281,7 +2281,35 @@ std::string Converter::GetEscapedStringLiteral(clang::Expr *expr,
22812281
return out;
22822282
}
22832283

2284+
std::string Converter::GetCodeUnitArrayLiteral(const clang::StringLiteral *expr,
2285+
uint64_t pad) {
2286+
auto elem_type =
2287+
ToStringBase(ctx_.getAsArrayType(expr->getType())->getElementType());
2288+
std::string out = "[";
2289+
for (unsigned i = 0; i < expr->getLength(); ++i) {
2290+
out += std::format("{} as {}, ", expr->getCodeUnit(i), elem_type);
2291+
}
2292+
for (uint64_t i = 0; i < pad; ++i) {
2293+
out += std::format("0 as {}, ", elem_type);
2294+
}
2295+
return out + ']';
2296+
}
2297+
22842298
bool Converter::VisitStringLiteral(clang::StringLiteral *expr) {
2299+
if (expr->getCharByteWidth() != 1 ||
2300+
expr->getKind() == clang::StringLiteralKind::UTF8) {
2301+
uint64_t pad = 1;
2302+
if (!curr_init_type_.empty() && curr_init_type_.back()->isArrayType()) {
2303+
if (auto *arr_ty = ctx_.getAsConstantArrayType(curr_init_type_.back())) {
2304+
uint64_t arr_size = arr_ty->getSize().getZExtValue();
2305+
pad = arr_size > expr->getLength() ? arr_size - expr->getLength() : 0;
2306+
}
2307+
}
2308+
StrCat(GetCodeUnitArrayLiteral(expr, pad));
2309+
computed_expr_type_ = ComputedExprType::FreshValue;
2310+
return false;
2311+
}
2312+
22852313
auto init_type = curr_init_type_.empty()
22862314
? clang::QualType()
22872315
: curr_init_type_.back().getNonReferenceType();

‎cpp2rust/converter/converter.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,8 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
349349
virtual bool VisitCharacterLiteral(clang::CharacterLiteral *expr);
350350

351351
std::string GetEscapedCharLiteral(char character) const;
352+
std::string GetCodeUnitArrayLiteral(const clang::StringLiteral *expr,
353+
uint64_t pad);
352354

353355
std::string GetEscapedUTF8CharLiteral(clang::Expr *expr) const;
354356

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,19 @@ void ConverterRefCount::PendingDeref::set_unchecked(std::string str, bool fresh,
8686
type = ComputedExprType::Pending;
8787
}
8888

89+
std::string
90+
ConverterRefCount::GetStringLiteralCodeUnit(const clang::Expr *expr) {
91+
const auto *literal = clang::dyn_cast<clang::StringLiteral>(
92+
expr->IgnoreParens()->IgnoreImplicit());
93+
if (literal == nullptr ||
94+
(literal->getCharByteWidth() == 1 &&
95+
literal->getKind() != clang::StringLiteralKind::UTF8)) {
96+
return "u8";
97+
}
98+
return ToStringBase(
99+
ctx_.getAsArrayType(literal->getType())->getElementType());
100+
}
101+
89102
std::string ConverterRefCount::GetInnerType(clang::QualType type) {
90103
PushConversionKind push(*this, ConversionKind::Unboxed);
91104
auto str = ToString(type);
@@ -1179,6 +1192,22 @@ bool ConverterRefCount::VisitCallExpr(clang::CallExpr *expr) {
11791192
}
11801193

11811194
bool ConverterRefCount::VisitStringLiteral(clang::StringLiteral *expr) {
1195+
if (expr->getCharByteWidth() != 1 ||
1196+
expr->getKind() == clang::StringLiteralKind::UTF8) {
1197+
uint64_t pad = 1;
1198+
if (!curr_init_type_.empty() && curr_init_type_.back()->isArrayType()) {
1199+
if (auto *arr_ty = ctx_.getAsConstantArrayType(curr_init_type_.back())) {
1200+
uint64_t arr_size = arr_ty->getSize().getZExtValue();
1201+
pad = arr_size > expr->getLength() ? arr_size - expr->getLength() : 0;
1202+
}
1203+
StrCat(std::format("Box::from({})", GetCodeUnitArrayLiteral(expr, pad)));
1204+
} else {
1205+
StrCat(std::format("&{}", GetCodeUnitArrayLiteral(expr, pad)));
1206+
}
1207+
computed_expr_type_ = ComputedExprType::FreshValue;
1208+
return false;
1209+
}
1210+
11821211
if (!curr_init_type_.empty() && curr_init_type_.back()->isArrayType()) {
11831212
uint64_t pad = 1;
11841213
if (auto *arr_ty = ctx_.getAsConstantArrayType(curr_init_type_.back())) {

‎cpp2rust/converter/models/converter_refcount.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,8 @@ class ConverterRefCount final : public Converter {
267267

268268
std::string GetInnerType(clang::QualType type);
269269

270+
std::string GetStringLiteralCodeUnit(const clang::Expr *expr);
271+
270272
std::string ConvertFreshLValue(clang::Expr *expr);
271273
std::string ConvertObject(clang::Expr *expr);
272274
std::string ConvertFreshObject(clang::Expr *expr) override;

‎tests/unit/out/unsafe/wide_char.rs‎

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ pub fn main() {
4444
}
4545
unsafe fn main_0() -> i32 {
4646
let mut c: *const libc::c_char = c"A".as_ptr();
47-
let mut w: *const i32 = (&[65 as i32, 258 as i32, 0 as i32]).as_ptr();
48-
let mut b: *const u8 = (&[196 as u8, 130 as u8, 0 as u8]).as_ptr();
49-
let mut s: *const u16 = (&[65 as u16, 258 as u16, 0 as u16]).as_ptr();
50-
let mut l: *const u32 = (&[65 as u32, 258 as u32, 0 as u32]).as_ptr();
47+
let mut w: *const i32 = [65 as i32, 258 as i32, 0 as i32].as_ptr();
48+
let mut b: *const u8 = [196 as u8, 130 as u8, 0 as u8].as_ptr();
49+
let mut s: *const u16 = [65 as u16, 258 as u16, 0 as u16].as_ptr();
50+
let mut l: *const u32 = [65 as u32, 258 as u32, 0 as u32].as_ptr();
5151
assert!((((*c.offset((0) as isize)) as i32) == (('A' as libc::c_char) as i32)));
5252
assert!(
5353
(((*b.offset((0) as isize)) as i32) == (196))
@@ -65,29 +65,29 @@ unsafe fn main_0() -> i32 {
6565
== (('A' as libc::c_char) as i32))
6666
);
6767
assert!(
68-
((*(unsafe { get_1((&[258 as i32, 0 as i32,]).as_ptr(),) }).offset((0) as isize)) == (258))
68+
((*(unsafe { get_1([258 as i32, 0 as i32,].as_ptr(),) }).offset((0) as isize)) == (258))
6969
);
7070
assert!(
71-
(((*(unsafe { get_2((&[196 as u8, 130 as u8, 0 as u8,]).as_ptr(),) }).offset((0) as isize))
71+
(((*(unsafe { get_2([196 as u8, 130 as u8, 0 as u8,].as_ptr(),) }).offset((0) as isize))
7272
as i32)
7373
== (196))
7474
);
7575
assert!(
76-
(((*(unsafe { get_3((&[258 as u16, 0 as u16,]).as_ptr(),) }).offset((0) as isize)) as i32)
76+
(((*(unsafe { get_3([258 as u16, 0 as u16,].as_ptr(),) }).offset((0) as isize)) as i32)
7777
== (258))
7878
);
7979
assert!(
80-
((*(unsafe { get_4((&[258 as u32, 0 as u32,]).as_ptr(),) }).offset((0) as isize))
80+
((*(unsafe { get_4([258 as u32, 0 as u32,].as_ptr(),) }).offset((0) as isize))
8181
== (258_u32))
8282
);
8383
assert!(
8484
(((unsafe { second_5(&std::mem::transmute(*b"AB\0"),) }) as i32)
8585
== (('B' as libc::c_char) as i32))
8686
);
87-
assert!(((unsafe { second_6(&(&[65 as i32, 258 as i32, 0 as i32,]),) }) == (258)));
88-
assert!((((unsafe { second_7(&(&[196 as u8, 130 as u8, 0 as u8,]),) }) as i32) == (130)));
89-
assert!((((unsafe { second_8(&(&[65 as u16, 258 as u16, 0 as u16,]),) }) as i32) == (258)));
90-
assert!(((unsafe { second_9(&(&[65 as u32, 258 as u32, 0 as u32,]),) }) == (258_u32)));
87+
assert!(((unsafe { second_6(&[65 as i32, 258 as i32, 0 as i32,],) }) == (258)));
88+
assert!((((unsafe { second_7(&[196 as u8, 130 as u8, 0 as u8,],) }) as i32) == (130)));
89+
assert!((((unsafe { second_8(&[65 as u16, 258 as u16, 0 as u16,],) }) as i32) == (258)));
90+
assert!(((unsafe { second_9(&[65 as u32, 258 as u32, 0 as u32,],) }) == (258_u32)));
9191
let nw: usize = ((::std::mem::size_of::<[i32; 4]>() as usize)
9292
.wrapping_div((::std::mem::size_of::<i32>() as usize)) as usize)
9393
.wrapping_sub(1_usize);

0 commit comments

Comments
 (0)