@@ -392,27 +392,20 @@ std::string ConverterRefCount::ConvertObject(clang::Expr *expr,
392392 return str;
393393}
394394
395- std::string
396- ConverterRefCount::ConvertFreshObject (clang::Expr *expr,
397- std::string_view target_ptr_type) {
398- auto shape = ObjectShape::Whole;
399- if (!target_ptr_type.empty ()) {
400- auto type = expr->getType ().getNonReferenceType ();
401- auto pointee = type->isPointerType () ? type->getPointeeType () : type;
402- if (IsBoxedType (ctx_, pointee) || pointee->isArrayType ()) {
403- auto normalize = [](std::string s) {
404- std::erase (s, ' ' );
405- for (size_t pos; (pos = s.find (" ::<" )) != std::string::npos;)
406- s.erase (pos, 2 );
407- return s;
408- };
409- if (normalize (std::string (target_ptr_type)) ==
410- normalize (ConvertPtrType (pointee))) {
411- shape = ObjectShape::Element;
412- }
413- }
414- }
415- auto str = ConvertObject (expr, shape);
395+ std::string ConverterRefCount::AsPointerMethod (clang::QualType type) const {
396+ return isObject () && WantsElementPtr () &&
397+ type.getNonReferenceType ()->isRecordType ()
398+ ? " .as_pointer().decay()"
399+ : " .as_pointer()" ;
400+ }
401+
402+ std::string ConverterRefCount::ConvertPointerReceiver (clang::Expr *arg,
403+ std::string_view) {
404+ return isObject () ? ConvertObject (arg) : ConvertFreshObject (arg);
405+ }
406+
407+ std::string ConverterRefCount::ConvertFreshObject (clang::Expr *expr) {
408+ auto str = ConvertObject (expr);
416409 if (isFresh ()) {
417410 return str;
418411 }
@@ -1072,11 +1065,12 @@ void ConverterRefCount::ConvertDeclRefValue(clang::Expr *expr,
10721065
10731066 if (isAddrOf ()) {
10741067 if (is_global_value) {
1075- StrCat (std::format (" {}.with(|v| v.as_pointer())" , std::move (str)));
1068+ StrCat (std::format (" {}.with(|v| v{})" , std::move (str),
1069+ AsPointerMethod (decl_t )));
10761070 } else if (is_global_ptr) {
10771071 StrCat (str);
10781072 } else {
1079- StrCat (str, " .as_pointer() " );
1073+ StrCat (str, AsPointerMethod ( decl_t ) );
10801074 }
10811075 computed_expr_type_ = ComputedExprType::FreshPointer;
10821076 return ;
@@ -1353,7 +1347,7 @@ bool ConverterRefCount::VisitCallExpr(clang::CallExpr *expr) {
13531347
13541348 if (isAddrOf () && !ty->isReferenceType () && !IsPointerType (ctx_, ty)) {
13551349 PushConversionKind push (*this , ConversionKind::FullRefCount);
1356- StrCat (BoxValue (std::move (str)), " .as_pointer() " );
1350+ StrCat (BoxValue (std::move (str)), AsPointerMethod (ty) );
13571351 return false ;
13581352 }
13591353
@@ -2090,7 +2084,7 @@ bool ConverterRefCount::VisitMemberExpr(clang::MemberExpr *expr) {
20902084 if (member->getType ()->isReferenceType ()) {
20912085 computed_expr_type_ = ComputedExprType::Pointer;
20922086 } else {
2093- StrCat (" .as_pointer() " );
2087+ StrCat (AsPointerMethod (member-> getType ()) );
20942088 computed_expr_type_ = ComputedExprType::FreshPointer;
20952089 }
20962090 return false ;
@@ -2125,8 +2119,8 @@ void ConverterRefCount::ConvertInlineField(clang::MemberExpr *expr) {
21252119 StrCat (std::format (" array_field_ptr!({}, {})" , ConvertRecordPtr (expr),
21262120 name));
21272121 } else if (IsBoxedType (ctx_, type)) {
2128- StrCat (std::format (" field_ref!({}, {}).as_pointer() " ,
2129- ConvertRecordPtr (expr), name ));
2122+ StrCat (std::format (" field_ref!({}, {}){} " , ConvertRecordPtr (expr), name ,
2123+ AsPointerMethod (type) ));
21302124 } else {
21312125 StrCat (std::format (" field_ptr!({}, {})" , ConvertRecordPtr (expr), name));
21322126 }
@@ -2838,28 +2832,17 @@ bool ConverterRefCount::ConvertCXXOperatorCallExpr(
28382832 StrCat (GetPointerDerefPrefix (expr->getType ()));
28392833 }
28402834
2841- if (is_inner_boxed && !isObject ()) {
2842- StrCat (' (' );
2843- }
2844-
28452835 PushConversionKind push (*this , ConversionKind::Unboxed);
28462836 if (deref && !is_inner_boxed) {
28472837 StrCat (ConvertElemPlace (expr->getArg (0 ), expr->getArg (1 )));
28482838 } else {
2849- StrCat (std::format (" ({} as {}) .offset({})" ,
2839+ StrCat (std::format (" {} .offset({})" ,
28502840 ConvertObject (expr->getArg (0 ), ObjectShape::Element),
2851- ConvertPtrType (expr->getArg (0 )->getType ()),
28522841 ConvertSubscriptIndex (expr->getArg (1 ))));
28532842 }
28542843
2855- // The pointer to the element is already a pointer to the whole inner
2856- // container, which as_pointer can't tell from a pointer to its first
2857- // element without a type.
2858- if (is_inner_boxed && (!isObject () || WantsElementPtr ())) {
2859- StrCat (" .as_pointer()" );
2860- if (!isObject ()) {
2861- StrCat (std::format (" as Ptr<{}>)" , ToString (expr->getType ())));
2862- }
2844+ if (is_inner_boxed && isObject () && WantsElementPtr ()) {
2845+ StrCat (" .decay()" );
28632846 }
28642847
28652848 if (isAddrOf ()) {
@@ -2918,10 +2901,9 @@ std::string ConverterRefCount::ConvertElemPlace(clang::Expr *container,
29182901 return std::format (" index!({}, {})" , place, ConvertSubscriptIndex (idx));
29192902 }
29202903 }
2921- auto ptr =
2922- std::format (" ({} as {})" , ConvertObject (container, ObjectShape::Element),
2923- ConvertPtrType (container->getType ()));
2924- return std::format (" elem!({}, {})" , ptr, ConvertSubscriptIndex (idx));
2904+ return std::format (" elem!({}, {})" ,
2905+ ConvertObject (container, ObjectShape::Element),
2906+ ConvertSubscriptIndex (idx));
29252907}
29262908
29272909void ConverterRefCount::ConvertFunctionParameters (clang::FunctionDecl *decl) {
@@ -3420,8 +3402,8 @@ void ConverterRefCount::SetUFCSReceiver(clang::Expr *base, bool is_arrow,
34203402 if (IsTemporaryObject (base) && base->getType ()->isRecordType () &&
34213403 !IsReferenceType (base->IgnoreImplicit ())) {
34223404 PushConversionKind push (*this , ConversionKind::FullRefCount);
3423- ufcs_receiver_ =
3424- token:: kRef + BoxValue ( ConvertRValue (base)) + " .as_pointer() " ;
3405+ ufcs_receiver_ = token:: kRef + BoxValue ( ConvertRValue (base)) +
3406+ AsPointerMethod (base-> getType ()) ;
34253407 return ;
34263408 }
34273409 ufcs_receiver_ = token::kRef + (base_is_pointer ? ConvertRValue (base)
0 commit comments