@@ -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
@@ -1173,6 +1181,8 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
11731181 ->getPointeeType ()
11741182 ->getAsArrayTypeUnsafe ()
11751183 ->getElementType ())));
1184+ } else if (IsStringLiteralExpr (sub_expr)) {
1185+ StrCat (std::format (" {}.to_any()" , ConvertFreshPointer (sub_expr)));
11761186 } else {
11771187 StrCat (std::format (" ({} as {}).to_any()" , ConvertFreshPointer (sub_expr),
11781188 ToString (sub_expr->getType ())));
@@ -1212,9 +1222,9 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
12121222 Convert (sub_expr);
12131223 return false ;
12141224 }
1215- if (clang::isa<clang::StringLiteral> (sub_expr) ||
1216- clang::isa<clang::PredefinedExpr>(sub_expr)) {
1217- 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 () )));
12181228 return false ;
12191229 } else {
12201230 // we need to write (var.as_pointer as Ptr<T>) because Rust isn't
@@ -1318,6 +1328,7 @@ bool ConverterRefCount::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) {
13181328 return false ;
13191329 }
13201330 if (expr->getCastKind () == clang::CK_NullToPointer) {
1331+ PushConversionKind push (*this , ConversionKind::Unboxed);
13211332 StrCat (GetDefaultAsString (expr->getType ()));
13221333 computed_expr_type_ = ComputedExprType::FreshPointer;
13231334 return false ;
@@ -1333,8 +1344,29 @@ bool ConverterRefCount::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) {
13331344 return false ;
13341345 case clang::Stmt::CStyleCastExprClass:
13351346 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+
13361365 if (!VisitFunctionPointerCast (expr)) {
13371366 return false ;
1367+ } else if (expr->getSubExpr ()->getType ()->isVoidPointerType () &&
1368+ expr->getType ()->isVoidPointerType ()) {
1369+ return Convert (expr->getSubExpr ());
13381370 } else if (expr->getSubExpr ()->getType ()->isVoidPointerType () &&
13391371 expr->getType ()->isPointerType ()) {
13401372 Convert (expr->getSubExpr ());
@@ -1889,7 +1921,9 @@ ConverterRefCount::GetArrayDefaultAsString(clang::QualType qual_type) {
18891921 const auto &size = array_type->getSize ();
18901922 auto size_as_string = GetNumAsString (size);
18911923 auto element_type = array_type->getElementType ();
1892- PushConversionKind push (*this , ConversionKind::Unboxed);
1924+ PushConversionKind push (*this , element_type->isArrayType ()
1925+ ? ConversionKind::FullRefCount
1926+ : ConversionKind::Unboxed);
18931927 auto element_type_as_string = ToString (element_type);
18941928 auto default_as_string = GetDefaultAsString (element_type);
18951929 return std::format (" (0..{}).map(|_| {}).collect::<Box<[{}]>>()" ,
@@ -1957,35 +1991,34 @@ ConverterRefCount::GetStructAttributes(const clang::RecordDecl *decl) {
19571991 return attrs;
19581992}
19591993
1960- void ConverterRefCount::ConvertVarInit (clang::QualType qual_type,
1961- clang::Expr *expr) {
1994+ std::string ConverterRefCount::ConvertVarInitValue (clang::QualType qual_type,
1995+ clang::Expr *expr) {
19621996 if (auto lambda = clang::dyn_cast<clang::LambdaExpr>(
19631997 expr->IgnoreUnlessSpelledInSource ())) {
1964- std::string str;
1965- {
1966- Buffer buf (*this );
1967- PushConversionKind push (*this , ConversionKind::Unboxed);
1968- if (qual_type->isFunctionPointerType () && lambda->capture_size () == 0 ) {
1969- StrCat (" FnPtr::new(" );
1970- VisitLambdaExpr (lambda);
1971- StrCat (' )' );
1972- } else {
1973- VisitLambdaExpr (lambda);
1974- }
1975- 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);
19762006 }
1977- StrCat (BoxValue (std::move (str)));
1978- return ;
2007+ return std::move (buf).str ();
19792008 }
19802009
1981- bool is_ref = qual_type->isReferenceType ();
1982- PushConversionKind push (*this , ConversionKind::Unboxed, is_ref);
19832010 PushInitType init_type (*this , qual_type);
1984- if (is_ref || qual_type->isFunctionPointerType ()) {
1985- StrCat (BoxValue (ConvertFreshPointer (expr)));
1986- } else {
1987- StrCat (BoxValue (ConvertFreshRValue (expr, qual_type)));
2011+ if (qual_type->isReferenceType () || qual_type->isFunctionPointerType ()) {
2012+ return ConvertFreshPointer (expr);
19882013 }
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)));
19892022}
19902023
19912024void ConverterRefCount::EmitSetOrAssign (clang::Expr *lhs,
@@ -2157,7 +2190,7 @@ bool ConverterRefCount::ConvertCXXOperatorCallExpr(
21572190 pending_deref_.set (std::format (" ({} as {}).offset({})" ,
21582191 ConvertObject (expr->getArg (0 )),
21592192 ConvertPtrType (expr->getArg (0 )->getType ()),
2160- ConvertRValue (expr->getArg (1 ))),
2193+ ConvertSubscriptIndex (expr->getArg (1 ))),
21612194 expr);
21622195 break ;
21632196 }
@@ -2177,7 +2210,7 @@ bool ConverterRefCount::ConvertCXXOperatorCallExpr(
21772210 StrCat (std::format (" ({} as {}).offset({})" ,
21782211 ConvertObject (expr->getArg (0 )),
21792212 ConvertPtrType (expr->getArg (0 )->getType ()),
2180- ConvertRValue (expr->getArg (1 ))));
2213+ ConvertSubscriptIndex (expr->getArg (1 ))));
21812214
21822215 if (is_inner_boxed) {
21832216 StrCat (GetPointerDerefSuffix (expr->getType ()), " .as_pointer()" );
@@ -2212,6 +2245,14 @@ void ConverterRefCount::ConvertFunctionParameters(clang::FunctionDecl *decl) {
22122245 }
22132246}
22142247
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+
22152256void ConverterRefCount::ConvertArraySubscript (clang::Expr *base,
22162257 clang::Expr *idx,
22172258 clang::QualType type) {
@@ -2225,10 +2266,16 @@ void ConverterRefCount::ConvertArraySubscript(clang::Expr *base,
22252266
22262267 {
22272268 PushParen paren (*this , is_inner_boxed);
2228- StrCat (std::format (" ({} as {}).offset({})" ,
2229- ToString (base->IgnoreImplicit ()),
2230- ConvertPtrType (base->IgnoreImplicit ()->getType ()),
2231- 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+ }
22322279
22332280 if (is_inner_boxed) {
22342281 StrCat (GetPointerDerefSuffix (type), " .as_pointer()" );
0 commit comments