Skip to content

Commit 4e55bc6

Browse files
committed
Make poitnee cast and scalar cast symetric
1 parent a3e8b8f commit 4e55bc6

6 files changed

Lines changed: 51 additions & 43 deletions

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,48 +1558,57 @@ bool Converter::VisitContinueStmt([[maybe_unused]] clang::ContinueStmt *stmt) {
15581558
bool Converter::Convert(clang::Expr *expr,
15591559
std::optional<clang::QualType> implicit_convert_to) {
15601560
if (expr && implicit_convert_to) {
1561-
if (auto pointee =
1562-
GetMismatchedExprPointee(ctx_, expr, *implicit_convert_to);
1563-
!pointee.isNull()) {
1564-
StrCat(ConvertPointeeCast(ToString(expr), pointee, *implicit_convert_to));
1565-
return true;
1561+
auto to = *implicit_convert_to;
1562+
if (NeedsImplicitPointeeCast(ctx_, expr, to)) {
1563+
StrCat(ConvertPointeeCast(ToString(expr), expr, to));
1564+
return false;
1565+
}
1566+
if (NeedsImplicitScalarCast(ctx_, expr->IgnoreImplicit()->getType(), to)) {
1567+
StrCat(ConvertScalarCast(ToString(expr), to));
1568+
return false;
15661569
}
15671570
}
1568-
bool needs_conversion =
1569-
expr && implicit_convert_to &&
1570-
NeedsImplicitScalarCast(ctx_, expr->IgnoreImplicit()->getType(),
1571-
*implicit_convert_to);
1572-
PushParen paren(*this, needs_conversion);
15731571
computed_expr_type_ = ComputedExprType::Unknown;
15741572
bool result = TraverseStmt(expr);
15751573
if (expr && computed_expr_type_ == ComputedExprType::Unknown) {
15761574
expr->dump();
15771575
assert(false && "computed_expr_type_ not set");
15781576
}
1579-
if (needs_conversion) {
1580-
ConvertCast(*implicit_convert_to);
1581-
computed_expr_type_ = ComputedExprType::FreshValue;
1582-
}
15831577
return result;
15841578
}
15851579

1580+
std::string Converter::ConvertScalarCast(std::string str, clang::QualType to) {
1581+
Buffer buf(*this);
1582+
{
1583+
PushParen paren(*this);
1584+
StrCat(str);
1585+
ConvertCast(to);
1586+
}
1587+
computed_expr_type_ = ComputedExprType::FreshValue;
1588+
return std::move(buf).str();
1589+
}
1590+
15861591
std::string Converter::ConvertPointeeCast(std::string str,
1587-
clang::QualType from,
1592+
const clang::Expr *from,
15881593
clang::QualType to) {
1594+
auto pointee = GetExprPointee(ctx_, from, to);
15891595
if (to->isFunctionPointerType()) {
15901596
return std::format("std::mem::transmute::<{}, {}>({})",
1591-
ToString(ctx_.getPointerType(from)), ToString(to),
1597+
ToString(ctx_.getPointerType(pointee)), ToString(to),
15921598
str);
15931599
}
1600+
if (to->getPointeeType().isConstQualified()) {
1601+
pointee = pointee.withConst();
1602+
}
15941603
auto target = GetUnsafeTypeAsString(to->getPointeeType());
15951604
if (to->isReferenceType() && !isAddrOf()) {
15961605
return std::format("*(&raw {} {}).cast::<{}>()",
1597-
from.isConstQualified() ? "const" : "mut", str,
1606+
pointee.isConstQualified() ? "const" : "mut", str,
15981607
target);
15991608
}
16001609
computed_expr_type_ = ComputedExprType::FreshPointer;
16011610
return std::format("({} as {}).cast::<{}>()", str,
1602-
GetUnsafeTypeAsString(ctx_.getPointerType(from)),
1611+
GetUnsafeTypeAsString(ctx_.getPointerType(pointee)),
16031612
target);
16041613
}
16051614

‎cpp2rust/converter/converter.h‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,10 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
312312
virtual void ConvertParamTyConstCast(clang::QualType param_type,
313313
clang::Expr *expr);
314314

315+
std::string ConvertScalarCast(std::string str, clang::QualType to);
316+
315317
virtual std::string ConvertPointeeCast(std::string str,
316-
clang::QualType from,
318+
const clang::Expr *from,
317319
clang::QualType to);
318320

319321
void ConvertFunctionPointerTransmute(clang::Expr *expr, clang::QualType type);

‎cpp2rust/converter/converter_lib.cpp‎

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,11 +1560,10 @@ bool NeedsImplicitScalarCast(clang::ASTContext &ctx, clang::QualType from,
15601560
Mapper::Map(ctx, from) != Mapper::Map(ctx, to);
15611561
}
15621562

1563-
static clang::QualType GetExprPointee(clang::ASTContext &ctx,
1564-
const clang::Expr *expr,
1565-
clang::QualType slot) {
1566-
auto type = expr->IgnoreImplicit()->getType().getNonReferenceType();
1567-
if (slot->isReferenceType()) {
1563+
clang::QualType GetExprPointee(clang::ASTContext &ctx, const clang::Expr *from,
1564+
clang::QualType to) {
1565+
auto type = from->IgnoreImplicit()->getType().getNonReferenceType();
1566+
if (to->isReferenceType()) {
15681567
return type;
15691568
}
15701569
if (auto *array = ctx.getAsArrayType(type)) {
@@ -1615,22 +1614,18 @@ static bool PointeeMappingDiffers(clang::ASTContext &ctx, clang::QualType from,
16151614
Mapper::Map(ctx, from) != Mapper::Map(ctx, to);
16161615
}
16171616

1618-
clang::QualType GetMismatchedExprPointee(clang::ASTContext &ctx,
1619-
const clang::Expr *expr,
1620-
clang::QualType slot) {
1621-
if (!slot->isReferenceType() && !slot->isPointerType()) {
1622-
return {};
1623-
}
1624-
if (slot->isReferenceType() &&
1625-
clang::isa<clang::MaterializeTemporaryExpr>(expr->IgnoreImpCasts())) {
1626-
return {};
1617+
bool NeedsImplicitPointeeCast(clang::ASTContext &ctx, const clang::Expr *from,
1618+
clang::QualType to) {
1619+
if (!to->isReferenceType() && !to->isPointerType()) {
1620+
return false;
16271621
}
1628-
auto pointee = GetExprPointee(ctx, expr, slot);
1629-
auto target = slot->getPointeeType();
1630-
if (pointee.isNull() || !PointeeMappingDiffers(ctx, pointee, target)) {
1631-
return {};
1622+
if (to->isReferenceType() &&
1623+
clang::isa<clang::MaterializeTemporaryExpr>(from->IgnoreImpCasts())) {
1624+
return false;
16321625
}
1633-
return target.isConstQualified() ? pointee.withConst() : pointee;
1626+
auto pointee = GetExprPointee(ctx, from, to);
1627+
return !pointee.isNull() &&
1628+
PointeeMappingDiffers(ctx, pointee, to->getPointeeType());
16341629
}
16351630

16361631
bool NeedsRefBindingTemp(clang::ASTContext &ctx, const clang::Expr *arg,

‎cpp2rust/converter/converter_lib.h‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,11 @@ bool IsVaListType(clang::QualType type);
276276
bool NeedsImplicitScalarCast(clang::ASTContext &ctx, clang::QualType from,
277277
clang::QualType to);
278278

279-
clang::QualType GetMismatchedExprPointee(clang::ASTContext &ctx,
280-
const clang::Expr *expr,
281-
clang::QualType slot);
279+
clang::QualType GetExprPointee(clang::ASTContext &ctx, const clang::Expr *from,
280+
clang::QualType to);
281+
282+
bool NeedsImplicitPointeeCast(clang::ASTContext &ctx, const clang::Expr *from,
283+
clang::QualType to);
282284

283285
bool NeedsRefBindingTemp(clang::ASTContext &ctx, const clang::Expr *arg,
284286
clang::QualType param_type);

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ std::string ConverterRefCount::ConvertFreshPointer(
408408
}
409409

410410
std::string ConverterRefCount::ConvertPointeeCast(std::string str,
411-
clang::QualType,
411+
const clang::Expr *,
412412
clang::QualType to) {
413413
if (to->isFunctionPointerType()) {
414414
computed_expr_type_ = ComputedExprType::FreshPointer;

‎cpp2rust/converter/models/converter_refcount.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ class ConverterRefCount final : public Converter {
377377

378378
void ConvertParamTyConstCast(clang::QualType, clang::Expr *) override {}
379379

380-
std::string ConvertPointeeCast(std::string str, clang::QualType from,
380+
std::string ConvertPointeeCast(std::string str, const clang::Expr *from,
381381
clang::QualType to) override;
382382

383383
std::string ConvertSubscriptIndex(clang::Expr *idx);

0 commit comments

Comments
 (0)