@@ -417,6 +417,14 @@ bool ConverterRefCount::VisitCXXRecordDecl(clang::CXXRecordDecl *decl) {
417417 return false ;
418418}
419419
420+ bool ConverterRefCount::VisitOffsetOfExpr (clang::OffsetOfExpr *expr) {
421+ clang::Expr::EvalResult result;
422+ ENSURE (expr->EvaluateAsInt (result, ctx_));
423+ StrCat (std::format (" {}_usize" , result.Val .getInt ().getZExtValue ()));
424+ computed_expr_type_ = ComputedExprType::FreshValue;
425+ return false ;
426+ }
427+
420428void ConverterRefCount::ConvertOrdAndPartialOrdTraits (
421429 const clang::CXXRecordDecl *decl, const clang::FunctionDecl *op) {
422430 std::string first_branch, second_branch, first_return, second_return;
@@ -723,10 +731,10 @@ void ConverterRefCount::EmitHoistedInArmAssignment(clang::VarDecl *decl) {
723731 if (!decl->hasInit ()) {
724732 return ;
725733 }
726- PushConversionKind push (*this , ConversionKind::Unboxed );
734+ PushConversionKind push (*this , ConversionKind::FullRefCount );
727735 StrCat (token::kStar , GetNamedDeclAsString (decl), " .borrow_mut()" ,
728736 token::kAssign );
729- Convert ( decl->getInit ());
737+ StrCat ( ConvertVarInitValue ( decl->getType (), decl-> getInit () ));
730738 StrCat (token::kSemiColon );
731739}
732740
@@ -1161,6 +1169,9 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
11611169
11621170 if (expr->getCastKind () == clang::CastKind::CK_BitCast) {
11631171 if (expr->getType ()->isVoidPointerType ()) {
1172+ if (sub_expr->getType ()->isVoidPointerType ()) {
1173+ return Convert (sub_expr);
1174+ }
11641175 PushConversionKind push (*this , ConversionKind::Unboxed);
11651176 if (sub_expr->getType ()->isPointerType () &&
11661177 sub_expr->getType ()->getPointeeType ()->isArrayType ()) {
@@ -1170,11 +1181,20 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
11701181 ->getPointeeType ()
11711182 ->getAsArrayTypeUnsafe ()
11721183 ->getElementType ())));
1184+ } else if (IsStringLiteralExpr (sub_expr)) {
1185+ StrCat (std::format (" {}.to_any()" , ConvertFreshPointer (sub_expr)));
11731186 } else {
11741187 StrCat (std::format (" ({} as {}).to_any()" , ConvertFreshPointer (sub_expr),
11751188 ToString (sub_expr->getType ())));
11761189 }
11771190 computed_expr_type_ = ComputedExprType::FreshPointer;
1191+ } else if (sub_expr->getType ()->isVoidPointerType () &&
1192+ expr->getType ()->isPointerType ()) {
1193+ Convert (sub_expr);
1194+ PushConversionKind push (*this , ConversionKind::Unboxed);
1195+ StrCat (std::format (" .reinterpret_cast::<{}>()" ,
1196+ ConvertPointeeType (expr->getType ())));
1197+ computed_expr_type_ = ComputedExprType::FreshPointer;
11781198 } else {
11791199 Convert (sub_expr);
11801200 }
@@ -1202,9 +1222,9 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
12021222 Convert (sub_expr);
12031223 return false ;
12041224 }
1205- if (clang::isa<clang::StringLiteral> (sub_expr) ||
1206- clang::isa<clang::PredefinedExpr>(sub_expr)) {
1207- StrCat ( std::format ( " Ptr::from_string_literal({}) " , ToString (sub_expr)));
1225+ if (IsStringLiteralExpr (sub_expr)) {
1226+ StrCat ( std::format ( " Ptr::from_string_literal({}) " ,
1227+ ToString (sub_expr-> IgnoreParens () )));
12081228 return false ;
12091229 } else {
12101230 // we need to write (var.as_pointer as Ptr<T>) because Rust isn't
@@ -1308,6 +1328,7 @@ bool ConverterRefCount::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) {
13081328 return false ;
13091329 }
13101330 if (expr->getCastKind () == clang::CK_NullToPointer) {
1331+ PushConversionKind push (*this , ConversionKind::Unboxed);
13111332 StrCat (GetDefaultAsString (expr->getType ()));
13121333 computed_expr_type_ = ComputedExprType::FreshPointer;
13131334 return false ;
@@ -1319,17 +1340,40 @@ bool ConverterRefCount::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) {
13191340 StrCat (
13201341 std::format (" {}.reinterpret_cast::<{}>()" , ToString (expr->getSubExpr ()),
13211342 GetUnsafeTypeAsString (expr->getType ()->getPointeeType ())));
1343+ computed_expr_type_ = ComputedExprType::FreshPointer;
13221344 return false ;
13231345 case clang::Stmt::CStyleCastExprClass:
13241346 case clang::Stmt::CXXStaticCastExprClass:
1347+ if (expr->getCastKind () == clang::CastKind::CK_PointerToIntegral ||
1348+ expr->getCastKind () == clang::CastKind::CK_IntegralToPointer) {
1349+ std::string dst_type;
1350+ {
1351+ PushConversionKind push (*this , ConversionKind::Unboxed);
1352+ dst_type = ToString (expr->getType ());
1353+ }
1354+ if (expr->getCastKind () == clang::CastKind::CK_PointerToIntegral) {
1355+ StrCat (std::format (" {}.to_int()" , ToString (expr->getSubExpr ())));
1356+ computed_expr_type_ = ComputedExprType::FreshValue;
1357+ } else {
1358+ StrCat (std::format (" <{}>::from_int({})" , dst_type,
1359+ ToString (expr->getSubExpr ())));
1360+ computed_expr_type_ = ComputedExprType::FreshPointer;
1361+ }
1362+ return false ;
1363+ }
1364+
13251365 if (!VisitFunctionPointerCast (expr)) {
13261366 return false ;
1367+ } else if (expr->getSubExpr ()->getType ()->isVoidPointerType () &&
1368+ expr->getType ()->isVoidPointerType ()) {
1369+ return Convert (expr->getSubExpr ());
13271370 } else if (expr->getSubExpr ()->getType ()->isVoidPointerType () &&
13281371 expr->getType ()->isPointerType ()) {
13291372 Convert (expr->getSubExpr ());
13301373 PushConversionKind push (*this , ConversionKind::Unboxed);
13311374 StrCat (std::format (" .reinterpret_cast::<{}>()" ,
13321375 ConvertPointeeType (expr->getType ())));
1376+ computed_expr_type_ = ComputedExprType::FreshPointer;
13331377 return false ;
13341378 } else if (expr->getType ()->isVoidPointerType () &&
13351379 expr->getSubExpr ()->getType ()->isPointerType ()) {
@@ -1343,6 +1387,7 @@ bool ConverterRefCount::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) {
13431387 StrCat (std::format (" {}.reinterpret_cast::<{}>()" ,
13441388 ToString (expr->getSubExpr ()),
13451389 ConvertPointeeType (expr->getType ())));
1390+ computed_expr_type_ = ComputedExprType::FreshPointer;
13461391 return false ;
13471392 }
13481393 return Converter::VisitExplicitCastExpr (expr);
@@ -1549,10 +1594,11 @@ void ConverterRefCount::ConvertUnionMemberAccessor(clang::MemberExpr *expr) {
15491594 " {}.reinterpret_cast::<{}>()" , str,
15501595 ToString (
15511596 member->getType ()->getAsArrayTypeUnsafe ()->getElementType ())));
1597+ computed_expr_type_ = ComputedExprType::FreshPointer;
15521598 } else {
15531599 StrCat (str);
1600+ computed_expr_type_ = ComputedExprType::Pointer;
15541601 }
1555- computed_expr_type_ = ComputedExprType::Pointer;
15561602 return ;
15571603 }
15581604
@@ -1875,7 +1921,9 @@ ConverterRefCount::GetArrayDefaultAsString(clang::QualType qual_type) {
18751921 const auto &size = array_type->getSize ();
18761922 auto size_as_string = GetNumAsString (size);
18771923 auto element_type = array_type->getElementType ();
1878- PushConversionKind push (*this , ConversionKind::Unboxed);
1924+ PushConversionKind push (*this , element_type->isArrayType ()
1925+ ? ConversionKind::FullRefCount
1926+ : ConversionKind::Unboxed);
18791927 auto element_type_as_string = ToString (element_type);
18801928 auto default_as_string = GetDefaultAsString (element_type);
18811929 return std::format (" (0..{}).map(|_| {}).collect::<Box<[{}]>>()" ,
@@ -1943,35 +1991,34 @@ ConverterRefCount::GetStructAttributes(const clang::RecordDecl *decl) {
19431991 return attrs;
19441992}
19451993
1946- void ConverterRefCount::ConvertVarInit (clang::QualType qual_type,
1947- clang::Expr *expr) {
1994+ std::string ConverterRefCount::ConvertVarInitValue (clang::QualType qual_type,
1995+ clang::Expr *expr) {
19481996 if (auto lambda = clang::dyn_cast<clang::LambdaExpr>(
19491997 expr->IgnoreUnlessSpelledInSource ())) {
1950- std::string str;
1951- {
1952- Buffer buf (*this );
1953- PushConversionKind push (*this , ConversionKind::Unboxed);
1954- if (qual_type->isFunctionPointerType () && lambda->capture_size () == 0 ) {
1955- StrCat (" FnPtr::new(" );
1956- VisitLambdaExpr (lambda);
1957- StrCat (' )' );
1958- } else {
1959- VisitLambdaExpr (lambda);
1960- }
1961- str = std::move (buf).str ();
1998+ Buffer buf (*this );
1999+ PushConversionKind push (*this , ConversionKind::Unboxed);
2000+ if (qual_type->isFunctionPointerType () && lambda->capture_size () == 0 ) {
2001+ StrCat (" FnPtr::new(" );
2002+ VisitLambdaExpr (lambda);
2003+ StrCat (' )' );
2004+ } else {
2005+ VisitLambdaExpr (lambda);
19622006 }
1963- StrCat (BoxValue (std::move (str)));
1964- return ;
2007+ return std::move (buf).str ();
19652008 }
19662009
1967- bool is_ref = qual_type->isReferenceType ();
1968- PushConversionKind push (*this , ConversionKind::Unboxed, is_ref);
19692010 PushInitType init_type (*this , qual_type);
1970- if (is_ref || qual_type->isFunctionPointerType ()) {
1971- StrCat (BoxValue (ConvertFreshPointer (expr)));
1972- } else {
1973- StrCat (BoxValue (ConvertFreshRValue (expr, qual_type)));
2011+ if (qual_type->isReferenceType () || qual_type->isFunctionPointerType ()) {
2012+ return ConvertFreshPointer (expr);
19742013 }
2014+ return ConvertFreshRValue (expr, qual_type);
2015+ }
2016+
2017+ void ConverterRefCount::ConvertVarInit (clang::QualType qual_type,
2018+ clang::Expr *expr) {
2019+ bool is_ref = qual_type->isReferenceType ();
2020+ PushConversionKind push (*this , ConversionKind::Unboxed, is_ref);
2021+ StrCat (BoxValue (ConvertVarInitValue (qual_type, expr)));
19752022}
19762023
19772024void ConverterRefCount::EmitSetOrAssign (clang::Expr *lhs,
@@ -2143,7 +2190,7 @@ bool ConverterRefCount::ConvertCXXOperatorCallExpr(
21432190 pending_deref_.set (std::format (" ({} as {}).offset({})" ,
21442191 ConvertObject (expr->getArg (0 )),
21452192 ConvertPtrType (expr->getArg (0 )->getType ()),
2146- ConvertRValue (expr->getArg (1 ))),
2193+ ConvertSubscriptIndex (expr->getArg (1 ))),
21472194 expr);
21482195 break ;
21492196 }
@@ -2163,7 +2210,7 @@ bool ConverterRefCount::ConvertCXXOperatorCallExpr(
21632210 StrCat (std::format (" ({} as {}).offset({})" ,
21642211 ConvertObject (expr->getArg (0 )),
21652212 ConvertPtrType (expr->getArg (0 )->getType ()),
2166- ConvertRValue (expr->getArg (1 ))));
2213+ ConvertSubscriptIndex (expr->getArg (1 ))));
21672214
21682215 if (is_inner_boxed) {
21692216 StrCat (GetPointerDerefSuffix (expr->getType ()), " .as_pointer()" );
@@ -2198,6 +2245,14 @@ void ConverterRefCount::ConvertFunctionParameters(clang::FunctionDecl *decl) {
21982245 }
21992246}
22002247
2248+ std::string ConverterRefCount::ConvertSubscriptIndex (clang::Expr *idx) {
2249+ auto str = ConvertRValue (idx);
2250+ if (idx->getType ()->isEnumeralType ()) {
2251+ return std::format (" ({}) as isize" , str);
2252+ }
2253+ return str;
2254+ }
2255+
22012256void ConverterRefCount::ConvertArraySubscript (clang::Expr *base,
22022257 clang::Expr *idx,
22032258 clang::QualType type) {
@@ -2211,10 +2266,16 @@ void ConverterRefCount::ConvertArraySubscript(clang::Expr *base,
22112266
22122267 {
22132268 PushParen paren (*this , is_inner_boxed);
2214- StrCat (std::format (" ({} as {}).offset({})" ,
2215- ToString (base->IgnoreImplicit ()),
2216- ConvertPtrType (base->IgnoreImplicit ()->getType ()),
2217- ConvertRValue (idx)));
2269+ if (IsStringLiteralExpr (base)) {
2270+ StrCat (std::format (" Ptr::from_string_literal({}).offset({})" ,
2271+ ToString (base->IgnoreParens ()->IgnoreImplicit ()),
2272+ ConvertSubscriptIndex (idx)));
2273+ } else {
2274+ StrCat (std::format (" ({} as {}).offset({})" ,
2275+ ToString (base->IgnoreImplicit ()),
2276+ ConvertPtrType (base->IgnoreImplicit ()->getType ()),
2277+ ConvertSubscriptIndex (idx)));
2278+ }
22182279
22192280 if (is_inner_boxed) {
22202281 StrCat (GetPointerDerefSuffix (type), " .as_pointer()" );
@@ -2459,6 +2520,7 @@ std::string ConverterRefCount::ConvertMappedMethodCall(
24592520
24602521std::string ConverterRefCount::ConvertPointeeType (clang::QualType ptr_type) {
24612522 assert (!ptr_type.isNull () && ptr_type->isPointerType ());
2523+ PushConversionKind push (*this , ConversionKind::Unboxed);
24622524 auto pointee = ptr_type->getPointeeType ();
24632525 if (!pointee->isRecordType ()) {
24642526 return ToString (pointee);
0 commit comments