@@ -1689,7 +1689,7 @@ std::string Converter::GetEscapedUTF8CharLiteral(clang::Expr *expr) const {
16891689}
16901690
16911691std::string Converter::GetEscapedStringLiteral (clang::Expr *expr,
1692- bool add_null_char ) const {
1692+ uint64_t pad_nulls ) const {
16931693 auto str_expr = clang::dyn_cast<clang::StringLiteral>(expr->IgnoreCasts ());
16941694 assert (str_expr);
16951695 auto raw = str_expr->getString ();
@@ -1698,15 +1698,31 @@ std::string Converter::GetEscapedStringLiteral(clang::Expr *expr,
16981698 for (unsigned char c : raw) {
16991699 out += GetEscapedCharLiteral (static_cast <char >(c));
17001700 }
1701- if (add_null_char ) {
1701+ for ( uint64_t i = 0 ; i < pad_nulls; ++i ) {
17021702 out += " \\ 0" ;
17031703 }
17041704 out.push_back (' "' );
17051705 return out;
17061706}
17071707
17081708bool Converter::VisitStringLiteral (clang::StringLiteral *expr) {
1709- StrCat (std::format (" b{}.as_ptr()" , GetEscapedStringLiteral (expr, true )));
1709+ if (!curr_init_type_.empty () && curr_init_type_.top ()->isArrayType ()) {
1710+ if (auto *arr_ty = ctx_.getAsConstantArrayType (curr_init_type_.top ())) {
1711+ uint64_t arr_size = arr_ty->getSize ().getZExtValue ();
1712+ if (expr->getString ().empty ()) {
1713+ StrCat (std::format (" [0u8; {}]" , arr_size));
1714+ return false ;
1715+ }
1716+ uint64_t pad = arr_size > expr->getString ().size ()
1717+ ? arr_size - expr->getString ().size ()
1718+ : 0 ;
1719+ StrCat (token::kStar ,
1720+ std::format (" b{}" , GetEscapedStringLiteral (expr, pad)));
1721+ return false ;
1722+ }
1723+ StrCat (token::kStar );
1724+ }
1725+ StrCat (std::format (" b{}" , GetEscapedStringLiteral (expr, 1 )));
17101726 return false ;
17111727}
17121728
@@ -1726,23 +1742,26 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
17261742 SetValueFreshness (type);
17271743 break ;
17281744 }
1729- case clang::CastKind::CK_ArrayToPointerDecay:
1730- if (clang::isa<clang::StringLiteral>(sub_expr) ||
1731- clang::isa<clang::PredefinedExpr>(sub_expr)) {
1732- return Convert (sub_expr);
1733- }
1745+ case clang::CastKind::CK_ArrayToPointerDecay: {
17341746 // __va_list_tag [1] decays to __va_list_tag *. Just pass through by value
17351747 if (IsVaListType (sub_expr->getType ())) {
17361748 Convert (sub_expr);
17371749 break ;
17381750 }
17391751 Convert (sub_expr);
1740- if (sub_expr->getType ().isConstQualified ()) {
1741- StrCat (keyword_ptr_decay_const_);
1752+ bool dest_pointee_const =
1753+ expr->getType ()->getPointeeType ().isConstQualified ();
1754+ if (clang::isa<clang::StringLiteral>(sub_expr) ||
1755+ clang::isa<clang::PredefinedExpr>(sub_expr)) {
1756+ StrCat (" .as_ptr()" );
1757+ if (!dest_pointee_const) {
1758+ StrCat (" .cast_mut()" );
1759+ }
17421760 } else {
1743- StrCat (keyword_ptr_decay_ );
1761+ StrCat (dest_pointee_const ? " .as_ptr() " : " .as_mut_ptr() " );
17441762 }
17451763 break ;
1764+ }
17461765 case clang::CastKind::CK_BitCast: {
17471766 PushParen paren (*this );
17481767 Convert (sub_expr);
@@ -1756,6 +1775,21 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
17561775 }
17571776 case clang::CastKind::CK_NoOp: {
17581777 Convert (sub_expr);
1778+ if (expr->getType ()->isPointerType () &&
1779+ sub_expr->getType ()->isPointerType () &&
1780+ !clang::isa<clang::CXXThisExpr>(expr->IgnoreImplicit ())) {
1781+ switch (GetConstCastType (expr->getType ()->getPointeeType (),
1782+ sub_expr->getType ()->getPointeeType ())) {
1783+ case ConstCastType::MutableToConst:
1784+ StrCat (" .cast_const()" );
1785+ break ;
1786+ case ConstCastType::ConstToMutable:
1787+ StrCat (" .cast_mut()" );
1788+ break ;
1789+ default :
1790+ break ;
1791+ }
1792+ }
17591793 break ;
17601794 }
17611795 case clang::CastKind::CK_FunctionToPointerDecay:
@@ -2973,9 +3007,8 @@ void Converter::ConvertVarInit(clang::QualType qual_type, clang::Expr *expr) {
29733007 if (auto *lambda = clang::dyn_cast<clang::LambdaExpr>(
29743008 expr->IgnoreUnlessSpelledInSource ())) {
29753009 PushExprKind push (*this , ExprKind::AddrOf);
2976- curr_init_type_. push ( qual_type);
3010+ PushInitType init_type (* this , qual_type);
29773011 VisitLambdaExpr (lambda);
2978- curr_init_type_.pop ();
29793012 return ;
29803013 }
29813014 }
@@ -2992,21 +3025,18 @@ void Converter::ConvertVarInit(clang::QualType qual_type, clang::Expr *expr) {
29923025 {
29933026 PushParen paren (*this );
29943027 StrCat (token::kStar );
2995- curr_init_type_. push ( qual_type);
3028+ PushInitType init_type (* this , qual_type);
29963029 Convert (expr);
2997- curr_init_type_.pop ();
29983030 }
29993031 StrCat (" .clone()" );
30003032 } else if (IsReferenceType (expr) || qual_type->isFunctionPointerType ()) {
30013033 PushExprKind push (*this , ExprKind::AddrOf);
3002- curr_init_type_. push ( qual_type);
3034+ PushInitType init_type (* this , qual_type);
30033035 Convert (expr);
3004- curr_init_type_.pop ();
30053036 } else {
30063037 PushExprKind push (*this , ExprKind::RValue);
3007- curr_init_type_. push ( qual_type);
3038+ PushInitType init_type (* this , qual_type);
30083039 Convert (expr);
3009- curr_init_type_.pop ();
30103040 }
30113041 if (qual_type->isReferenceType () && !IsReferenceType (expr)) {
30123042 StrCat (keyword::kAs );
@@ -3080,9 +3110,11 @@ void Converter::ConvertArraySubscript(clang::Expr *base, clang::Expr *idx,
30803110
30813111void Converter::ConvertAssignment (clang::Expr *lhs, clang::Expr *rhs,
30823112 std::string_view assign_operator) {
3083- curr_init_type_.push (lhs->getType ());
3084- auto lhs_as_string = ConvertLValue (lhs);
3085- curr_init_type_.pop ();
3113+ std::string lhs_as_string;
3114+ {
3115+ PushInitType init_type (*this , lhs->getType ());
3116+ lhs_as_string = ConvertLValue (lhs);
3117+ }
30863118 auto rhs_as_string = ConvertFreshRValue (rhs);
30873119
30883120 PushBrace brace (*this , !isVoid ());
0 commit comments