diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index cc8fe39c..84ba3300 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -25,8 +25,9 @@ std::unordered_set Converter::abstract_structs_; void Converter::ConvertUniquePtrDeref(clang::CXXOperatorCallExpr *expr) { bool is_star = expr->getOperator() == clang::OverloadedOperatorKind::OO_Star; + PushParen paren(*this, is_star); if (is_star) { - StrCat(token::kOpenParen, token::kStar); + StrCat(token::kStar); } if (expr->getArg(0)->IgnoreImplicit()->getType().isConstQualified()) { StrCat("(*(std::ptr::addr_of!("); @@ -36,9 +37,6 @@ void Converter::ConvertUniquePtrDeref(clang::CXXOperatorCallExpr *expr) { Convert(expr->getArg(0)); StrCat(".as_deref_mut().unwrap()"); } - if (is_star) { - StrCat(token::kCloseParen); - } } void Converter::EmitFilePreamble() { @@ -314,15 +312,17 @@ bool Converter::VisitFunctionDecl(clang::FunctionDecl *decl) { if (!decl->isMain()) ConvertFunctionQualifiers(decl); StrCat(decl->isConstexpr() ? keyword_const_fn_ : "", keyword_unsafe_, - keyword::kFn, std::move(function_name), token::kOpenParen); - ConvertFunctionParameters(decl); - StrCat(token::kCloseParen); + keyword::kFn, std::move(function_name)); + { + PushParen paren(*this); + ConvertFunctionParameters(decl); + } ConvertFunctionReturnType(decl); - StrCat(token::kOpenCurlyBracket); - EmitFunctionPreamble(decl); - ConvertFunctionBody(decl); - - StrCat(token::kCloseCurlyBracket); + { + PushBrace brace(*this); + EmitFunctionPreamble(decl); + ConvertFunctionBody(decl); + } if (decl->isOverloadedOperator()) { switch (decl->getOverloadedOperator()) { @@ -640,12 +640,13 @@ void Converter::EmitRustStruct(clang::RecordDecl *decl) { auto access = clang::dyn_cast(decl) ? AccessSpecifierAsString(decl->getAccess()) : keyword::kPub; - StrCat(access, keyword::kStruct, GetRecordName(decl), - token::kOpenCurlyBracket); - for (auto *field : decl->fields()) { - VisitFieldDecl(field); + StrCat(access, keyword::kStruct, GetRecordName(decl)); + { + PushBrace brace(*this); + for (auto *field : decl->fields()) { + VisitFieldDecl(field); + } } - StrCat(token::kCloseCurlyBracket); // C++ method decls if (auto *cxx = clang::dyn_cast(decl)) { @@ -700,10 +701,9 @@ bool Converter::VisitCXXRecordDecl(clang::CXXRecordDecl *decl) { if (decl->isStruct() || decl->isClass()) { for (auto c : GetTemplateInstantiatedCtors(decl)) { if (!decl_ids_.contains(GetID(c))) { - StrCat(std::string(keyword::kImpl) + ' ' + GetRecordName(decl), - token::kOpenCurlyBracket); + StrCat(std::string(keyword::kImpl) + ' ' + GetRecordName(decl)); + PushBrace brace(*this); VisitCXXMethodDecl(c); - StrCat(token::kCloseCurlyBracket); } } @@ -744,21 +744,17 @@ bool Converter::VisitCXXMethodDecl(clang::CXXMethodDecl *decl) { } curr_function_ = decl; - if (decl->isOutOfLine()) { - if (decl->overridden_methods().empty()) { - StrCat(keyword::kImpl, GetRecordName(decl->getParent()), - token::kOpenCurlyBracket); - } else { - return false; - } + if (decl->isOutOfLine() && !decl->overridden_methods().empty()) { + return false; + } + bool out_of_line = decl->isOutOfLine(); + if (out_of_line) { + StrCat(keyword::kImpl, GetRecordName(decl->getParent())); } + PushBrace impl_brace(*this, out_of_line); if (auto *ctor = clang::dyn_cast(decl)) { - auto result = VisitCXXConstructorDecl(ctor); - if (decl->isOutOfLine()) { - StrCat(token::kCloseCurlyBracket); - } - return result; + return VisitCXXConstructorDecl(ctor); } if (decl->isStatic() || @@ -775,24 +771,22 @@ bool Converter::VisitCXXMethodDecl(clang::CXXMethodDecl *decl) { } else { function_name = GetNamedDeclAsString(decl); } - StrCat(std::move(function_name), token::kOpenParen); + StrCat(std::move(function_name)); - if (!decl->isStatic()) { - StrCat(GetSelfMaybeWithMut(decl), token::kComma); + { + PushParen paren(*this); + if (!decl->isStatic()) { + StrCat(GetSelfMaybeWithMut(decl), token::kComma); + } + ConvertFunctionParameters(decl); } - ConvertFunctionParameters(decl); - StrCat(token::kCloseParen); ConvertFunctionReturnType(decl); if (decl->isPureVirtual()) { StrCat(token::kSemiColon); } else { - StrCat(token::kOpenCurlyBracket); + PushBrace body(*this); EmitFunctionPreamble(decl); ConvertFunctionBody(decl); - StrCat(token::kCloseCurlyBracket); - } - if (decl->isOutOfLine()) { - StrCat(token::kCloseCurlyBracket); } return false; } @@ -820,48 +814,54 @@ bool Converter::VisitCXXConstructorDecl(clang::CXXConstructorDecl *decl) { (GetNumberOfConvertingCtors(decl->getParent()) != 1 ? std::to_string(GetCtorIndex(decl)) : ""); - StrCat(keyword_unsafe_, keyword::kFn, ctor_name, token::kOpenParen); - ConvertFunctionParameters(decl); - - StrCat(token::kCloseParen, token::kArrow, "Self", token::kOpenCurlyBracket); - ConvertCXXConstructorBody(decl); - StrCat(token::kCloseCurlyBracket); + StrCat(keyword_unsafe_, keyword::kFn, ctor_name); + { + PushParen paren(*this); + ConvertFunctionParameters(decl); + } + StrCat(token::kArrow, "Self"); + { + PushBrace brace(*this); + ConvertCXXConstructorBody(decl); + } return false; } void Converter::ConvertCXXConstructorBody(clang::CXXConstructorDecl *decl) { EmitFunctionPreamble(decl); - StrCat(keyword::kLet, "mut", "this", token::kAssign, "Self", - token::kOpenCurlyBracket); - const auto *record_decl = decl->getParent(); - auto *definition_or_null = decl->getDefinition(); - assert(definition_or_null); - auto *definition = clang::cast(definition_or_null); - - bool has_inits = !definition->inits().empty(); - auto **ctor_initializer_list = definition->inits().begin(); - int curr_init = - has_inits ? (ctor_initializer_list[0]->isBaseInitializer() ? 1 : 0) : 0; - - for (const auto *field : record_decl->fields()) { - auto field_name = GetNamedDeclAsString(field); - auto field_type = field->getType(); - auto *ctor_initializer = - has_inits ? ctor_initializer_list[curr_init] : nullptr; - - if (has_inits && - GetNamedDeclAsString(ctor_initializer->getMember()) == field_name) { - auto *ctor_init_expr = ctor_initializer->getInit(); - StrCat(field_name, token::kColon); - ConvertVarInit(field_type, ctor_init_expr); - curr_init = (curr_init + 1) % definition->getNumCtorInitializers(); - } else { - StrCat(field_name, token::kColon, GetDefaultAsString(field_type)); + StrCat(keyword::kLet, "mut", "this", token::kAssign, "Self"); + { + PushBrace this_init(*this); + const auto *record_decl = decl->getParent(); + auto *definition_or_null = decl->getDefinition(); + assert(definition_or_null); + auto *definition = + clang::cast(definition_or_null); + + bool has_inits = !definition->inits().empty(); + auto **ctor_initializer_list = definition->inits().begin(); + int curr_init = + has_inits ? (ctor_initializer_list[0]->isBaseInitializer() ? 1 : 0) : 0; + + for (const auto *field : record_decl->fields()) { + auto field_name = GetNamedDeclAsString(field); + auto field_type = field->getType(); + auto *ctor_initializer = + has_inits ? ctor_initializer_list[curr_init] : nullptr; + + if (has_inits && + GetNamedDeclAsString(ctor_initializer->getMember()) == field_name) { + auto *ctor_init_expr = ctor_initializer->getInit(); + StrCat(field_name, token::kColon); + ConvertVarInit(field_type, ctor_init_expr); + curr_init = (curr_init + 1) % definition->getNumCtorInitializers(); + } else { + StrCat(field_name, token::kColon, GetDefaultAsString(field_type)); + } + StrCat(token::kComma); } - StrCat(token::kComma); } - StrCat(token::kCloseCurlyBracket); StrCat(token::kSemiColon); Convert(decl->getBody()); @@ -973,17 +973,17 @@ void Converter::ConvertCondition(clang::Expr *cond) { bool Converter::VisitIfStmt(clang::IfStmt *stmt) { StrCat(keyword::kIf); ConvertCondition(stmt->getCond()); - StrCat(token::kOpenCurlyBracket); - Convert(stmt->getThen()); - StrCat(token::kCloseCurlyBracket); + { + PushBrace brace(*this); + Convert(stmt->getThen()); + } if (stmt->hasElseStorage()) { StrCat(keyword::kElse); if (clang::isa(stmt->getElse())) { Convert(stmt->getElse()); } else { - StrCat(token::kOpenCurlyBracket); + PushBrace brace(*this); Convert(stmt->getElse()); - StrCat(token::kCloseCurlyBracket); } } return false; @@ -994,26 +994,34 @@ bool Converter::VisitWhileStmt(clang::WhileStmt *stmt) { StrCat("'loop_:"); StrCat(keyword::kWhile); ConvertCondition(stmt->getCond()); - StrCat(token::kOpenCurlyBracket); - curr_for_inc_.emplace(nullptr); - Convert(stmt->getBody()); - curr_for_inc_.pop(); - StrCat(token::kCloseCurlyBracket); + { + PushBrace brace(*this); + curr_for_inc_.emplace(nullptr); + Convert(stmt->getBody()); + curr_for_inc_.pop(); + } return false; } bool Converter::VisitDoStmt(clang::DoStmt *stmt) { PushBreakTarget push(break_target_, BreakTarget::Loop); StrCat("'loop_:"); - StrCat(keyword::kLoop, token::kOpenCurlyBracket); - curr_for_inc_.emplace(nullptr); - Convert(stmt->getBody()); - curr_for_inc_.pop(); - StrCat(keyword::kIf, token::kNot, token::kOpenParen); - ConvertCondition(stmt->getCond()); - StrCat(token::kCloseParen, token::kOpenCurlyBracket, keyword::kBreak, - token::kSemiColon, token::kCloseCurlyBracket, - token::kCloseCurlyBracket); + StrCat(keyword::kLoop); + { + PushBrace loop_brace(*this); + curr_for_inc_.emplace(nullptr); + Convert(stmt->getBody()); + curr_for_inc_.pop(); + StrCat(keyword::kIf, token::kNot); + { + PushParen paren(*this); + ConvertCondition(stmt->getCond()); + } + { + PushBrace if_brace(*this); + StrCat(keyword::kBreak, token::kSemiColon); + } + } return false; } @@ -1027,12 +1035,14 @@ bool Converter::VisitForStmt(clang::ForStmt *stmt) { } else { ConvertCondition(stmt->getCond()); } - StrCat(token::kOpenCurlyBracket); - curr_for_inc_.emplace(stmt->getInc()); - Convert(stmt->getBody()); - curr_for_inc_.pop(); - Convert(stmt->getInc()); - StrCat(token::kSemiColon, token::kCloseCurlyBracket); + { + PushBrace brace(*this); + curr_for_inc_.emplace(stmt->getInc()); + Convert(stmt->getBody()); + curr_for_inc_.pop(); + Convert(stmt->getInc()); + StrCat(token::kSemiColon); + } return false; } @@ -1096,9 +1106,10 @@ bool Converter::VisitCXXForRangeStmtMap(clang::CXXForRangeStmt *stmt) { "UnsafeMapIterator::begin(&"); Convert(stmt->getRangeInit()); StrCat(std::format(" as *const {})", map_type)); - StrCat(token::kOpenCurlyBracket); - ConvertForRangeBody(stmt, loop_var); - StrCat(token::kCloseCurlyBracket); + { + PushBrace brace(*this); + ConvertForRangeBody(stmt, loop_var); + } return false; } @@ -1117,24 +1128,29 @@ bool Converter::VisitCXXForRangeStmtIndexBased(clang::CXXForRangeStmt *stmt, auto loop_var_name = GetNamedDeclAsString(loop_var); StrCat("'loop_:"); - StrCat(keyword::kFor, loop_var_name, keyword::kIn, "0..", token::kOpenParen); - Convert(stmt->getRangeInit()); - StrCat(token::kDot, len_suffix, token::kCloseParen, token::kOpenCurlyBracket, - keyword::kLet); - - auto loop_var_type = loop_var->getType(); - if (!loop_var_type.isConstQualified()) { - StrCat(keyword_mut_); + StrCat(keyword::kFor, loop_var_name, keyword::kIn, "0.."); + { + PushParen range(*this); + Convert(stmt->getRangeInit()); + StrCat(token::kDot, len_suffix); } + { + PushBrace body(*this); + StrCat(keyword::kLet); - StrCat(loop_var_name); - StrCat(token::kAssign); + auto loop_var_type = loop_var->getType(); + if (!loop_var_type.isConstQualified()) { + StrCat(keyword_mut_); + } - ConvertLoopVariable(loop_var, stmt->getRangeInit()); + StrCat(loop_var_name); + StrCat(token::kAssign); - StrCat(token::kSemiColon); - ConvertForRangeBody(stmt); - StrCat(token::kCloseCurlyBracket); + ConvertLoopVariable(loop_var, stmt->getRangeInit()); + + StrCat(token::kSemiColon); + ConvertForRangeBody(stmt); + } return false; } @@ -1416,8 +1432,10 @@ bool Converter::VisitCallExpr(clang::CallExpr *expr) { auto ref = clang::dyn_cast(ty); if (ref && !isAddrOf() && !isVoid()) { - StrCat(token::kOpenParen, GetPointerDerefPrefix(ref->getPointeeType()), str, - token::kCloseParen); + { + PushParen paren(*this); + StrCat(GetPointerDerefPrefix(ref->getPointeeType()), str); + } SetValueFreshness(ref->getPointeeType()); return false; } @@ -1427,9 +1445,11 @@ bool Converter::VisitCallExpr(clang::CallExpr *expr) { } void Converter::EmitFnPtrCall(clang::Expr *callee) { - StrCat(token::kOpenParen); - Convert(callee); - StrCat(").unwrap()"); + { + PushParen paren(*this); + Convert(callee); + } + StrCat(".unwrap()"); } void Converter::ConvertFunctionToFunctionPointer( @@ -1456,9 +1476,9 @@ void Converter::ConvertGenericCallExpr(clang::CallExpr *expr) { } } - StrCat(token::kOpenParen); + PushParen outer(*this); StrCat(keyword_unsafe_); - StrCat(token::kOpenCurlyBracket); + PushBrace unsafe_brace(*this); const auto *function = expr->getCalleeDecl() ? expr->getCalleeDecl()->getAsFunction() : nullptr; const clang::FunctionProtoType *proto = nullptr; @@ -1514,47 +1534,46 @@ void Converter::ConvertGenericCallExpr(clang::CallExpr *expr) { PushExprKind push(*this, ExprKind::Callee); Convert(callee); } - StrCat(token::kOpenParen); - for (unsigned i = 0; i < num_named_params && i < num_args; ++i) { - auto *arg = expr->getArg(i + arg_begin); - std::string param_name = function - ? function->getParamDecl(i)->getNameAsString() - : ("arg" + std::to_string(i)); - clang::QualType param_type = function ? function->getParamDecl(i)->getType() - : proto->getParamType(i); - bool is_parm_with_default_value = - function && function->getParamDecl(i)->hasDefaultArg(); - - if (is_parm_with_default_value) { - StrCat("Some("); - } - if (!temp_refs[i].empty()) { - StrCat(temp_refs[i]); - } else if (clang::isa(arg)) { - convert_param_ty(param_type, arg); - } else { - StrCat(std::format("_{}", param_name)); - } - if (is_parm_with_default_value) { - StrCat(")"); + { + PushParen call_args(*this); + for (unsigned i = 0; i < num_named_params && i < num_args; ++i) { + auto *arg = expr->getArg(i + arg_begin); + std::string param_name = + function ? function->getParamDecl(i)->getNameAsString() + : ("arg" + std::to_string(i)); + clang::QualType param_type = function + ? function->getParamDecl(i)->getType() + : proto->getParamType(i); + bool is_parm_with_default_value = + function && function->getParamDecl(i)->hasDefaultArg(); + + if (is_parm_with_default_value) { + StrCat("Some("); + } + if (!temp_refs[i].empty()) { + StrCat(temp_refs[i]); + } else if (clang::isa(arg)) { + convert_param_ty(param_type, arg); + } else { + StrCat(std::format("_{}", param_name)); + } + if (is_parm_with_default_value) { + StrCat(")"); + } + StrCat(token::kComma); } - StrCat(token::kComma); - } - // Variadic args: wrap in &[arg.into(), ...] - if (is_variadic) { - StrCat("& ["); - for (unsigned i = num_named_params; i < num_args; ++i) { - auto *arg = expr->getArg(i + arg_begin); - Convert(arg); - StrCat(".into()", token::kComma); + // Variadic args: wrap in &[arg.into(), ...] + if (is_variadic) { + StrCat("& ["); + for (unsigned i = num_named_params; i < num_args; ++i) { + auto *arg = expr->getArg(i + arg_begin); + Convert(arg); + StrCat(".into()", token::kComma); + } + StrCat("]"); } - StrCat("]"); } - - StrCat(token::kCloseParen); - StrCat(token::kCloseCurlyBracket); - StrCat(token::kCloseParen); } std::optional @@ -1621,8 +1640,10 @@ bool Converter::VisitFloatingLiteral(clang::FloatingLiteral *expr) { bool Converter::VisitCharacterLiteral(clang::CharacterLiteral *expr) { std::string ch = GetEscapedCharLiteral(expr->getValue()); ch = "'" + std::move(ch) + "'"; - StrCat(token::kOpenParen, ch, keyword::kAs, ToStringBase(expr->getType()), - token::kCloseParen); + { + PushParen paren(*this); + StrCat(ch, keyword::kAs, ToStringBase(expr->getType())); + } computed_expr_type_ = ComputedExprType::FreshValue; return false; } @@ -1718,8 +1739,8 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { StrCat(keyword_ptr_decay_); } break; - case clang::CastKind::CK_BitCast: - StrCat(token::kOpenParen); + case clang::CastKind::CK_BitCast: { + PushParen paren(*this); Convert(sub_expr); if (type->isVoidPointerType()) { StrCat(keyword::kAs, @@ -1727,8 +1748,8 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { Convert(sub_expr->getType()->getPointeeType()); } ConvertCast(type); - StrCat(token::kCloseParen); break; + } case clang::CastKind::CK_NoOp: { Convert(sub_expr); break; @@ -1757,9 +1778,11 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { } } - StrCat(token::kOpenParen); - Convert(sub_expr); - StrCat(token::kDiff, token::kZero, token::kCloseParen); + { + PushParen paren(*this); + Convert(sub_expr); + StrCat(token::kDiff, token::kZero); + } break; case clang::CastKind::CK_PointerToBoolean: StrCat(token::kNot); @@ -1786,17 +1809,19 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { Convert(sub_expr); break; } - StrCat(token::kOpenParen); - StrCat(token::kOpenParen); - Convert(sub_expr); - if (clang::isa(sub_expr)) { - StrCat(token::kCloseParen); - ConvertCast(type); - StrCat(token::kCloseParen); - } else { - ConvertCast(type); - StrCat(token::kCloseParen); - StrCat(token::kCloseParen); + { + PushParen outer(*this); + if (clang::isa(sub_expr)) { + { + PushParen inner(*this); + Convert(sub_expr); + } + ConvertCast(type); + } else { + PushParen inner(*this); + Convert(sub_expr); + ConvertCast(type); + } } } return false; @@ -1826,16 +1851,17 @@ bool Converter::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) { StrCat(")"); return false; } - StrCat(token::kOpenParen); - Convert(sub_expr); - if (auto *unary_oper = clang::dyn_cast(sub_expr); - unary_oper && unary_oper->getOpcode() == clang::UO_AddrOf && - (clang::isa(unary_oper->getSubExpr()) || - clang::isa(unary_oper->getSubExpr()))) { - ConvertCast(sub_expr->getType()); + { + PushParen paren(*this); + Convert(sub_expr); + if (auto *unary_oper = clang::dyn_cast(sub_expr); + unary_oper && unary_oper->getOpcode() == clang::UO_AddrOf && + (clang::isa(unary_oper->getSubExpr()) || + clang::isa(unary_oper->getSubExpr()))) { + ConvertCast(sub_expr->getType()); + } + ConvertCast(type); } - ConvertCast(type); - StrCat(token::kCloseParen); return false; default: Convert(sub_expr); @@ -1858,22 +1884,25 @@ bool Converter::VisitBinaryOperator(clang::BinaryOperator *expr) { auto computation_result_type = cmpd_assign_op->getComputationResultType(); if (IsUnsignedArithOp(cmpd_assign_op)) { Convert(lhs); - StrCat(token::kAssign, token::kOpenParen, token::kOpenParen); - Convert(lhs); - ConvertCast(computation_result_type); - StrCat(token::kCloseParen); + StrCat(token::kAssign); + PushParen outer(*this); + { + PushParen inner(*this); + Convert(lhs); + ConvertCast(computation_result_type); + } ConvertUnsignedArithBinaryOperator(expr, rhs); - StrCat(token::kCloseParen); } else { Convert(lhs); - StrCat(token::kAssign, token::kOpenParen); - StrCat(token::kOpenParen); - Convert(lhs); - ConvertCast(computation_result_type); - StrCat(token::kCloseParen); + StrCat(token::kAssign); + PushParen outer(*this); + { + PushParen inner(*this); + Convert(lhs); + ConvertCast(computation_result_type); + } StrCat(std::regex_replace(opcode_as_string, std::regex("="), "")); Convert(rhs); - StrCat(token::kCloseParen); } if (lhs_type->isBooleanType()) { StrCat(token::kDiff, token::kZero); @@ -1889,9 +1918,10 @@ bool Converter::VisitBinaryOperator(clang::BinaryOperator *expr) { Convert(lhs); StrCat(token::kAssign); } - StrCat(token::kOpenParen); - ConvertUnsignedArithOperand(lhs, type); - StrCat(token::kCloseParen); + { + PushParen paren(*this); + ConvertUnsignedArithOperand(lhs, type); + } ConvertUnsignedArithBinaryOperator(expr, rhs); } else if (expr->isAssignmentOp()) { if (expr->isCompoundAssignmentOp() && @@ -1899,9 +1929,10 @@ bool Converter::VisitBinaryOperator(clang::BinaryOperator *expr) { expr->getRHS()->getType()->isIntegralOrEnumerationType()) { Convert(lhs); StrCat(token::kAssign); - StrCat(token::kOpenParen); - ConvertUnsignedArithOperand(lhs, type); - StrCat(token::kCloseParen); + { + PushParen paren(*this); + ConvertUnsignedArithOperand(lhs, type); + } ConvertUnsignedArithBinaryOperator(expr, rhs); } else { ConvertAssignment(lhs, rhs, opcode_as_string); @@ -1910,9 +1941,9 @@ bool Converter::VisitBinaryOperator(clang::BinaryOperator *expr) { if (expr->getOpcode() == clang::BO_EQ) { ConvertEqualsNullPtr(lhs); } else { - StrCat(token::kNot, token::kOpenParen); + StrCat(token::kNot); + PushParen paren(*this); ConvertEqualsNullPtr(lhs); - StrCat(token::kCloseParen); } } else if (expr->isAdditiveOp() && expr->getType()->isPointerType()) { auto [base, idx] = lhs_type->isPointerType() ? std::make_tuple(lhs, rhs) @@ -1920,15 +1951,22 @@ bool Converter::VisitBinaryOperator(clang::BinaryOperator *expr) { ConvertPointerOffset(base, idx, expr->getOpcode() == clang::BO_Add); } else if (expr->isAdditiveOp() && lhs_type->isPointerType() && rhs_type->isPointerType()) { - StrCat(token::kOpenParen, token::kOpenParen); - Convert(lhs); - StrCat(keyword::kAs, "usize", token::kMinus); - Convert(rhs); - StrCat(keyword::kAs, "usize", token::kCloseParen, token::kDiv); - auto pointee_type_as_string = ToString(lhs_type->getPointeeType()); - auto size_of_as_string = - std::format("::std::mem::size_of::<{}>()", pointee_type_as_string); - StrCat(size_of_as_string, token::kCloseParen, keyword::kAs, "u64"); + { + PushParen outer(*this); + { + PushParen inner(*this); + Convert(lhs); + StrCat(keyword::kAs, "usize", token::kMinus); + Convert(rhs); + StrCat(keyword::kAs, "usize"); + } + StrCat(token::kDiv); + auto pointee_type_as_string = ToString(lhs_type->getPointeeType()); + auto size_of_as_string = + std::format("::std::mem::size_of::<{}>()", pointee_type_as_string); + StrCat(size_of_as_string); + } + StrCat(keyword::kAs, "u64"); computed_expr_type_ = ComputedExprType::FreshValue; } else { ConvertGenericBinaryOperator(expr); @@ -1937,17 +1975,16 @@ bool Converter::VisitBinaryOperator(clang::BinaryOperator *expr) { } void Converter::ConvertGenericBinaryOperator(clang::BinaryOperator *expr) { - StrCat(token::kOpenParen); - StrCat(token::kOpenParen); - Convert(expr->getLHS()); - StrCat(token::kCloseParen); + PushParen outer(*this); + { + PushParen lhs_paren(*this); + Convert(expr->getLHS()); + } StrCat(expr->getOpcodeStr()); - StrCat(token::kOpenParen); + PushParen rhs_paren(*this); Convert(expr->getRHS()); - StrCat(token::kCloseParen); - StrCat(token::kCloseParen); } bool Converter::IsReferenceType(const clang::Expr *expr) const { @@ -2015,11 +2052,11 @@ bool Converter::VisitUnaryOperator(clang::UnaryOperator *expr) { return false; } switch (opcode) { - case clang::UO_AddrOf: - StrCat(token::kOpenParen); + case clang::UO_AddrOf: { + PushParen paren(*this); ConvertAddrOf(sub_expr, expr->getType()); - StrCat(token::kCloseParen); break; + } case clang::UO_Deref: ConvertDeref(sub_expr); break; @@ -2051,17 +2088,21 @@ bool Converter::VisitUnaryOperator(clang::UnaryOperator *expr) { bool Converter::VisitConditionalOperator(clang::ConditionalOperator *expr) { StrCat(keyword::kIf); Convert(expr->getCond()); - StrCat(token::kOpenCurlyBracket); - if (expr->isLValue() && !isRValue() && !expr->getType()->isFunctionType()) { - StrCat(token::kRef, keyword_mut_); + { + PushBrace then_brace(*this); + if (expr->isLValue() && !isRValue() && !expr->getType()->isFunctionType()) { + StrCat(token::kRef, keyword_mut_); + } + Convert(expr->getTrueExpr()); } - Convert(expr->getTrueExpr()); - StrCat(token::kCloseCurlyBracket, keyword::kElse, token::kOpenCurlyBracket); - if (expr->isLValue() && !isRValue() && !expr->getType()->isFunctionType()) { - StrCat(token::kRef, keyword_mut_); + StrCat(keyword::kElse); + { + PushBrace else_brace(*this); + if (expr->isLValue() && !isRValue() && !expr->getType()->isFunctionType()) { + StrCat(token::kRef, keyword_mut_); + } + Convert(expr->getFalseExpr()); } - Convert(expr->getFalseExpr()); - StrCat(token::kCloseCurlyBracket); return false; } @@ -2104,9 +2145,11 @@ bool Converter::VisitDeclRefExpr(clang::DeclRefExpr *expr) { if (decl->getType()->getAs() && !isAddrOf() && !map_iter_decls_.contains(clang::dyn_cast(decl))) { - StrCat(token::kOpenParen, - GetPointerDerefPrefix(decl->getType().getNonReferenceType()), - std::move(str), token::kCloseParen); + { + PushParen paren(*this); + StrCat(GetPointerDerefPrefix(decl->getType().getNonReferenceType()), + std::move(str)); + } SetValueFreshness(expr->getType()); return false; } @@ -2123,9 +2166,8 @@ bool Converter::VisitDeclRefExpr(clang::DeclRefExpr *expr) { if (auto init = var_decl->getInit()) { if (auto lambda = clang::dyn_cast( init->IgnoreUnlessSpelledInSource())) { - StrCat(token::kOpenParen); + PushParen paren(*this); VisitLambdaExpr(lambda); - StrCat(token::kCloseParen); return false; } } @@ -2148,17 +2190,15 @@ bool Converter::VisitParenExpr(clang::ParenExpr *expr) { bool should_add_integral_cast = expr->getType()->isIntegralOrEnumerationType() && !isAddrOf() && !clang::isa(expr->getSubExpr()); - if (should_add_integral_cast) { - StrCat(token::kOpenParen); - } + PushParen outer(*this, should_add_integral_cast); - StrCat(token::kOpenParen); - Convert(expr->getSubExpr()); - StrCat(token::kCloseParen); + { + PushParen inner(*this); + Convert(expr->getSubExpr()); + } if (should_add_integral_cast) { ConvertCast(expr->getType()); - StrCat(token::kCloseParen); } return false; } @@ -2176,9 +2216,9 @@ bool Converter::ConvertCXXOperatorCallExpr(clang::CXXOperatorCallExpr *expr) { IteratorCategory::Bidirectional) { Convert(expr->getArg(0)); } else if (expr->getOperator() == clang::OverloadedOperatorKind::OO_Star) { - StrCat(token::kOpenParen, token::kStar); + PushParen paren(*this); + StrCat(token::kStar); Convert(expr->getArg(0)); - StrCat(token::kCloseParen); } else { Convert(expr->getArg(0)); } @@ -2200,16 +2240,18 @@ bool Converter::ConvertCXXOperatorCallExpr(clang::CXXOperatorCallExpr *expr) { if (clang::isa(callee)) { Convert(expr->getArg(0)); if (callee->isUserProvided()) { - StrCat(token::kDot, GetOverloadedOperator(callee), token::kOpenParen); - StrCat(ConvertPointer(expr->getArg(1)), token::kCloseParen); + StrCat(token::kDot, GetOverloadedOperator(callee)); + PushParen paren(*this); + StrCat(ConvertPointer(expr->getArg(1))); } else { StrCat(token::kLt); Convert(expr->getArg(1)); } } else { - StrCat(GetOverloadedOperator(callee), token::kOpenParen, - ConvertFreshPointer(expr->getArg(0)), token::kComma, - ConvertFreshPointer(expr->getArg(1)), token::kCloseParen); + StrCat(GetOverloadedOperator(callee)); + PushParen paren(*this); + StrCat(ConvertFreshPointer(expr->getArg(0)), token::kComma, + ConvertFreshPointer(expr->getArg(1))); } } computed_expr_type_ = ComputedExprType::FreshValue; @@ -2249,14 +2291,14 @@ bool Converter::VisitMemberExpr(clang::MemberExpr *expr) { } if (!isAddrOf() && member->getType()->isReferenceType()) { - StrCat(token::kOpenParen, - GetPointerDerefPrefix(member->getType().getNonReferenceType()), str, - token::kCloseParen); + PushParen paren(*this); + StrCat(GetPointerDerefPrefix(member->getType().getNonReferenceType()), str); return false; } if (!isAddrOf() && member->getType()->isFunctionPointerType()) { - StrCat(token::kOpenParen, str, token::kCloseParen); + PushParen paren(*this); + StrCat(str); return false; } @@ -2331,16 +2373,16 @@ bool Converter::VisitInitListExpr(clang::InitListExpr *expr) { return false; } - StrCat(GetUnsafeTypeAsString(qual_type), token::kOpenCurlyBracket); + StrCat(GetUnsafeTypeAsString(qual_type)); + PushBrace brace(*this); int i = 0; for (const auto *field : record->fields()) { StrCat(GetNamedDeclAsString(field), token::kColon); ConvertVarInit(field->getType(), expr->getInit(i++)); StrCat(token::kComma); } - StrCat(token::kCloseCurlyBracket); } else { - StrCat(token::kOpenBracket); + PushBracket bracket(*this); for (auto *init : expr->inits()) { ConvertVarInit(init->getType(), init); StrCat(token::kComma); @@ -2358,7 +2400,6 @@ bool Converter::VisitInitListExpr(clang::InitListExpr *expr) { } } } - StrCat(token::kCloseBracket); } return false; } @@ -2461,10 +2502,11 @@ bool Converter::VisitCXXDeleteExpr(clang::CXXDeleteExpr *expr) { } void Converter::ConvertArrayCXXConstructExpr(clang::CXXConstructExpr *expr) { - StrCat(std::format("std::array::from_fn::<_, {}, _>(|_|", + StrCat(std::format("std::array::from_fn::<_, {}, _>", GetArraySize(expr->getType()))); + PushParen paren(*this); + StrCat("|_|"); ConvertCXXConstructExprArgs(expr); - StrCat(token::kCloseParen); } void Converter::ConvertCXXConstructExprArgs(clang::CXXConstructExpr *expr) { @@ -2473,8 +2515,8 @@ void Converter::ConvertCXXConstructExprArgs(clang::CXXConstructExpr *expr) { StrCat(ctor_name, token::kDoubleColon, ctor_name + (GetNumberOfConvertingCtors(ctor->getParent()) != 1 ? std::to_string(GetCtorIndex(ctor)) - : ""), - token::kOpenParen); + : "")); + PushParen paren(*this); unsigned arg_idx = 0; for (unsigned param_idx = 0; param_idx < ctor->getNumParams(); ++param_idx) { @@ -2498,8 +2540,6 @@ void Converter::ConvertCXXConstructExprArgs(clang::CXXConstructExpr *expr) { } StrCat(token::kComma); } - - StrCat(token::kCloseParen); } bool Converter::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) { @@ -2589,7 +2629,7 @@ bool Converter::VisitLambdaExpr(clang::LambdaExpr *expr) { if (isAddrOf() && expr->capture_size() == 0) { StrCat("Some"); } - StrCat(token::kOpenParen); + PushParen paren(*this); StrCat("|"); for (auto p : expr->getLambdaClass()->getLambdaCallOperator()->parameters()) { StrCat(GetNamedDeclAsString(p), token::kColon, ToString(p->getType()), @@ -2602,7 +2642,7 @@ bool Converter::VisitLambdaExpr(clang::LambdaExpr *expr) { curr_function_ = expr->getLambdaClass()->getLambdaCallOperator(); ConvertFunctionBody(curr_function_); curr_function_ = old_function; - StrCat("}", token::kCloseParen); + StrCat("}"); return false; } @@ -2894,11 +2934,14 @@ void Converter::ConvertVarInit(clang::QualType qual_type, clang::Expr *expr) { ->getCallee()) && Mapper::ToString(ctor->getConstructor()->getThisType()) == "std::string") { - StrCat(token::kOpenParen, token::kStar); - curr_init_type_.push(qual_type); - Convert(expr); - curr_init_type_.pop(); - StrCat(token::kCloseParen, ".clone()"); + { + PushParen paren(*this); + StrCat(token::kStar); + curr_init_type_.push(qual_type); + Convert(expr); + curr_init_type_.pop(); + } + StrCat(".clone()"); } else if (IsReferenceType(expr) || qual_type->isFunctionPointerType()) { PushExprKind push(*this, ExprKind::AddrOf); curr_init_type_.push(qual_type); @@ -2943,21 +2986,26 @@ void Converter::ConvertPointerSubscript(clang::ArraySubscriptExpr *expr) { if (isAddrOf()) { ConvertPointerOffset(base, idx); } else { - StrCat(token::kOpenParen, token::kStar); + PushParen paren(*this); + StrCat(token::kStar); ConvertPointerOffset(base, idx); - StrCat(token::kCloseParen); } } void Converter::ConvertPointerOffset(clang::Expr *base, clang::Expr *idx, bool is_addition) { Convert(base); - StrCat(token::kDot, "offset", token::kOpenParen, - is_addition ? "" : token::kMinus, token::kOpenParen, - is_addition ? "" : token::kOpenParen); - Convert(idx); - StrCat(token::kCloseParen, keyword::kAs, "isize", - is_addition ? "" : token::kCloseParen, token::kCloseParen); + StrCat(token::kDot, "offset"); + PushParen outer(*this); + if (!is_addition) { + StrCat(token::kMinus); + } + PushParen neg_paren(*this, !is_addition); + { + PushParen inner(*this); + Convert(idx); + } + StrCat(keyword::kAs, "isize"); computed_expr_type_ = ComputedExprType::FreshPointer; } @@ -2967,9 +3015,12 @@ void Converter::ConvertArraySubscript(clang::Expr *base, clang::Expr *idx, if (IsUniquePtr(base->getType())) { StrCat(".as_mut().unwrap()"); } - StrCat(token::kOpenBracket, token::kOpenParen); - Convert(idx); - StrCat(token::kCloseParen, keyword::kAs, "usize", token::kCloseBracket); + PushBracket bracket(*this); + { + PushParen paren(*this); + Convert(idx); + } + StrCat(keyword::kAs, "usize"); } void Converter::ConvertAssignment(clang::Expr *lhs, clang::Expr *rhs, @@ -2979,13 +3030,11 @@ void Converter::ConvertAssignment(clang::Expr *lhs, clang::Expr *rhs, curr_init_type_.pop(); auto rhs_as_string = ConvertFreshRValue(rhs); - if (!isVoid()) { - StrCat(token::kOpenCurlyBracket); - } + PushBrace brace(*this, !isVoid()); StrCat(lhs_as_string, assign_operator, rhs_as_string); if (!isVoid()) { - StrCat(token::kSemiColon, ConvertRValue(lhs), token::kCloseCurlyBracket); + StrCat(token::kSemiColon, ConvertRValue(lhs)); } } @@ -3059,11 +3108,11 @@ void Converter::ConvertCXXMethodDecls(const clang::CXXRecordDecl *decl, if (methods.empty()) { return; } - StrCat(signature, token::kOpenCurlyBracket); + StrCat(signature); + PushBrace brace(*this); for (auto *method : methods) { VisitCXXMethodDecl(method); } - StrCat(token::kCloseCurlyBracket); } void Converter::ConvertOrdAndPartialOrdTraitsBase( @@ -3154,11 +3203,13 @@ void Converter::AddDefaultTrait(const clang::CXXRecordDecl *decl) { return; } auto struct_name = GetRecordName(decl); - StrCat(std::format("impl Default for {}", struct_name), - token::kOpenCurlyBracket, "fn default() -> Self", - token::kOpenCurlyBracket); + StrCat(std::format("impl Default for {}", struct_name)); + PushBrace impl_brace(*this); + StrCat("fn default() -> Self"); + PushBrace fn_brace(*this); if (auto *default_ctor = GetUserDefinedDefaultConstructor(decl)) { - StrCat(keyword_unsafe_, token::kOpenCurlyBracket); + StrCat(keyword_unsafe_); + PushBrace unsafe_brace(*this); Convert(clang::CXXConstructExpr::Create( ctx_, ctx_.getCanonicalTagType(decl), clang::SourceLocation(), default_ctor, @@ -3168,16 +3219,14 @@ void Converter::AddDefaultTrait(const clang::CXXRecordDecl *decl) { /*StdInitListInitialization=*/false, /*ZeroInitialization=*/false, clang::CXXConstructionKind::Complete, clang::SourceRange())); - StrCat(token::kCloseCurlyBracket); } else { - StrCat(struct_name, token::kOpenCurlyBracket); + StrCat(struct_name); + PushBrace struct_brace(*this); for (auto *field : decl->fields()) { StrCat(GetNamedDeclAsString(field), token::kColon, GetDefaultAsString(field->getType()), token::kComma); } - StrCat(token::kCloseCurlyBracket); } - StrCat(token::kCloseCurlyBracket, token::kCloseCurlyBracket); } void Converter::AddByteReprTrait(const clang::RecordDecl *decl) {} @@ -3213,7 +3262,7 @@ void Converter::ConvertUnsignedArithBinaryOperator(clang::BinaryOperator *op, op->dumpColor(); assert(0); } - StrCat(token::kOpenParen); + PushParen paren(*this); auto type = op->getType(); bool is_pointer_plus_integer_op = false; @@ -3231,7 +3280,6 @@ void Converter::ConvertUnsignedArithBinaryOperator(clang::BinaryOperator *op, if (is_pointer_plus_integer_op) { StrCat("as usize"); } - StrCat(token::kCloseParen); } void Converter::ConvertAddrOf(clang::Expr *expr, clang::QualType pointer_type) { @@ -3251,9 +3299,9 @@ void Converter::ConvertAddrOf(clang::Expr *expr, clang::QualType pointer_type) { void Converter::ConvertDeref(clang::Expr *expr) { if (!isAddrOf()) { - StrCat(token::kOpenParen, - GetPointerDerefPrefix(expr->getType()->getPointeeType()), - ToString(expr), token::kCloseParen); + PushParen paren(*this); + StrCat(GetPointerDerefPrefix(expr->getType()->getPointeeType()), + ToString(expr)); } else { Convert(expr); } diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index a0a14931..d25cea2f 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -328,6 +328,32 @@ class Converter : public clang::RecursiveASTVisitor { std::string str() && { return std::move(partial_code); } }; + template class PushDelim { + Converter &c; + bool enabled; + + public: + PushDelim(Converter &c, bool enabled = true) : c(c), enabled(enabled) { + if (enabled) { + c.StrCat(kOpen); + } + } + ~PushDelim() { + if (enabled) { + c.StrCat(kClose); + } + } + PushDelim(const PushDelim &) = delete; + PushDelim(PushDelim &&) = delete; + PushDelim &operator=(const PushDelim &) = delete; + PushDelim &operator=(PushDelim &&) = delete; + }; + + using PushBrace = + PushDelim; + using PushParen = PushDelim; + using PushBracket = PushDelim; + template inline std::string ToString(T node) { Buffer buf(*this); Convert(node); diff --git a/cpp2rust/converter/lex.h b/cpp2rust/converter/lex.h index bf7b5673..db69958d 100644 --- a/cpp2rust/converter/lex.h +++ b/cpp2rust/converter/lex.h @@ -5,32 +5,32 @@ namespace cpp2rust { namespace token { -inline constexpr const char *kOpenCurlyBracket = "{\n"; -inline constexpr const char *kCloseCurlyBracket = "\n}\n"; -inline constexpr const char *kOpenBracket = "["; -inline constexpr const char *kCloseBracket = "]"; +inline constexpr char kOpenCurlyBracket = '{'; +inline constexpr char kCloseCurlyBracket = '}'; +inline constexpr char kOpenBracket = '['; +inline constexpr char kCloseBracket = ']'; inline constexpr const char *kSemiColon = ";\n"; -inline constexpr const char *kComma = ","; -inline constexpr const char *kColon = ":"; +inline constexpr char kComma = ','; +inline constexpr char kColon = ':'; inline constexpr const char *kDoubleColon = "::"; inline constexpr const char *kAssign = "="; -inline constexpr const char *kOpenParen = "("; -inline constexpr const char *kCloseParen = ")"; -inline constexpr const char *kDot = "."; -inline constexpr const char *kNot = "!"; +inline constexpr char kOpenParen = '('; +inline constexpr char kCloseParen = ')'; +inline constexpr char kDot = '.'; +inline constexpr char kNot = '!'; inline constexpr const char *kDiff = "!="; -inline constexpr const char *kZero = "0"; -inline constexpr const char *kOne = "1"; -inline constexpr const char *kRef = "&"; +inline constexpr char kZero = '0'; +inline constexpr char kOne = '1'; +inline constexpr char kRef = '&'; inline constexpr const char *kStar = "*"; inline constexpr const char *kArrow = "->"; -inline constexpr const char *kHash = "#"; -inline constexpr const char *kMinus = "-"; -inline constexpr const char *kDiv = "/"; -inline constexpr const char *kLt = "<"; -inline constexpr const char *kGt = ">"; +inline constexpr char kHash = '#'; +inline constexpr char kMinus = '-'; +inline constexpr char kDiv = '/'; +inline constexpr char kLt = '<'; +inline constexpr char kGt = '>'; inline constexpr const char *kEmpty = ""; -inline constexpr const char *kNewLine = "\n"; +inline constexpr char kNewLine = '\n'; } // namespace token namespace keyword { diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 460d8479..44b96092 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -385,9 +385,10 @@ bool ConverterRefCount::VisitArraySubscriptExpr( pending_deref_.set_unchecked(std::move(buf).str(), expr); return false; } - StrCat(token::kOpenParen, GetPointerDerefPrefix(expr->getType())); + PushParen paren(*this); + StrCat(GetPointerDerefPrefix(expr->getType())); ConvertArraySubscript(base, expr->getIdx(), expr->getType()); - StrCat(GetPointerDerefSuffix(expr->getType()), token::kCloseParen); + StrCat(GetPointerDerefSuffix(expr->getType())); } else { ConvertArraySubscript(base, expr->getIdx(), expr->getType()); } @@ -496,8 +497,8 @@ void ConverterRefCount::AddDropTrait(const clang::CXXRecordDecl *decl) { void ConverterRefCount::AddByteReprTrait(const clang::RecordDecl *decl) { auto struct_name = GetRecordName(decl); - StrCat(std::format("impl ByteRepr for {}", struct_name), - token::kOpenCurlyBracket, token::kCloseCurlyBracket); + StrCat(std::format("impl ByteRepr for {}", struct_name)); + PushBrace brace(*this); } std::string @@ -558,9 +559,12 @@ bool ConverterRefCount::ConvertLambdaVarDecl(clang::VarDecl *decl) { } void ConverterRefCount::ConvertGlobalVarDecl(clang::VarDecl *decl) { - StrCat("thread_local!", token::kOpenParen); - ConvertVarDecl(decl); - StrCat(token::kCloseParen, token::kSemiColon); + StrCat("thread_local!"); + { + PushParen paren(*this); + ConvertVarDecl(decl); + } + StrCat(token::kSemiColon); } bool ConverterRefCount::VisitVarDecl(clang::VarDecl *decl) { @@ -609,10 +613,16 @@ bool ConverterRefCount::ConvertIncAndDec(clang::UnaryOperator *expr) { bool ConverterRefCount::VisitConditionalOperator( clang::ConditionalOperator *expr) { - StrCat(keyword::kIf, ConvertRValue(expr->getCond()), token::kOpenCurlyBracket, - ConvertFresh(expr->getTrueExpr()), token::kCloseCurlyBracket, - keyword::kElse, token::kOpenCurlyBracket, - ConvertFresh(expr->getFalseExpr()), token::kCloseCurlyBracket); + StrCat(keyword::kIf, ConvertRValue(expr->getCond())); + { + PushBrace then_brace(*this); + StrCat(ConvertFresh(expr->getTrueExpr())); + } + StrCat(keyword::kElse); + { + PushBrace else_brace(*this); + StrCat(ConvertFresh(expr->getFalseExpr())); + } return false; } @@ -1010,8 +1020,8 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { // we need to write (var.as_pointer as Ptr) because Rust isn't // smart enough to pick the right specialization PushConversionKind push(*this, ConversionKind::Unboxed); - StrCat(token::kOpenParen, ConvertPointer(sub_expr), keyword::kAs, - ToString(expr->getType()), token::kCloseParen); + PushParen paren(*this); + StrCat(ConvertPointer(sub_expr), keyword::kAs, ToString(expr->getType())); return false; } } @@ -1141,21 +1151,22 @@ bool ConverterRefCount::VisitBinaryOperator(clang::BinaryOperator *expr) { auto computation_result_type = assign->getComputationResultType(); StrCat(keyword::kLet, "rhs_0", token::kAssign); if (IsUnsignedArithOp(assign)) { - StrCat(token::kOpenParen, token::kOpenParen); - StrCat(ConvertRValue(lhs)); - ConvertCast(computation_result_type); - StrCat(token::kCloseParen); + PushParen outer(*this); + { + PushParen inner(*this); + StrCat(ConvertRValue(lhs)); + ConvertCast(computation_result_type); + } ConvertUnsignedArithBinaryOperator(expr, rhs); - StrCat(token::kCloseParen); } else { - StrCat(token::kOpenParen); - StrCat(token::kOpenParen); - StrCat(ConvertRValue(lhs)); - ConvertCast(computation_result_type); - StrCat(token::kCloseParen); + PushParen outer(*this); + { + PushParen inner(*this); + StrCat(ConvertRValue(lhs)); + ConvertCast(computation_result_type); + } StrCat(std::regex_replace(opcode_as_string, std::regex("="), "")); Convert(rhs); - StrCat(token::kCloseParen); } if (lhs_type->isBooleanType()) { StrCat(token::kDiff, token::kZero); @@ -1171,13 +1182,14 @@ bool ConverterRefCount::VisitBinaryOperator(clang::BinaryOperator *expr) { if (expr->isCompoundAssignmentOp()) { StrCat(keyword::kLet, "rhs_0", token::kAssign); } - StrCat(token::kOpenParen); - if (expr->isCompoundAssignmentOp() && lhs->isLValue()) { - StrCat(ConvertRValue(lhs)); - } else { - ConvertUnsignedArithOperand(lhs, expr->getType()); + { + PushParen paren(*this); + if (expr->isCompoundAssignmentOp() && lhs->isLValue()) { + StrCat(ConvertRValue(lhs)); + } else { + ConvertUnsignedArithOperand(lhs, expr->getType()); + } } - StrCat(token::kCloseParen); ConvertUnsignedArithBinaryOperator(expr, rhs); if (expr->isCompoundAssignmentOp()) { StrCat(token::kSemiColon); @@ -1230,15 +1242,17 @@ bool ConverterRefCount::VisitInitListExpr(clang::InitListExpr *expr) { return false; } - StrCat(GetUnsafeTypeAsString(qual_type), token::kOpenCurlyBracket); - int i = 0; - PushConversionKind push(*this, ConversionKind::FullRefCount); - for (const auto *field : record->fields()) { - StrCat(GetNamedDeclAsString(field), token::kColon); - ConvertVarInit(field->getType(), expr->getInit(i++)); - StrCat(token::kComma); + StrCat(GetUnsafeTypeAsString(qual_type)); + { + PushBrace brace(*this); + int i = 0; + PushConversionKind push(*this, ConversionKind::FullRefCount); + for (const auto *field : record->fields()) { + StrCat(GetNamedDeclAsString(field), token::kColon); + ConvertVarInit(field->getType(), expr->getInit(i++)); + StrCat(token::kComma); + } } - StrCat(token::kCloseCurlyBracket); computed_expr_type_ = ComputedExprType::FreshValue; return false; } @@ -1381,14 +1395,13 @@ bool ConverterRefCount::VisitCXXForRangeStmtMap(clang::CXXForRangeStmt *stmt) { StrCat("'loop_:"); StrCat(keyword::kFor, loop_var_name, keyword::kIn, "RefcountMapIter::begin(", ConvertObject(stmt->getRangeInit()), ")"); - StrCat(token::kOpenCurlyBracket); + PushBrace brace(*this); EmitByValueShadow( loop_var_name, loop_var->getType(), std::string(loop_var_name), "Value<" + Mapper::Map(GetForRangeIteratorType(stmt)) + ">"); ConvertForRangeBody(stmt, loop_var); - StrCat(token::kCloseCurlyBracket); return false; } @@ -1404,7 +1417,7 @@ bool ConverterRefCount::VisitCXXForRangeStmtVector( loop_var_name, keyword::kIn, ConvertObject(stmt->getRangeInit())); StrCat(keyword::kAs, ConvertPtrType(stmt->getRangeInit()->getType())); - StrCat(token::kOpenCurlyBracket); + PushBrace brace(*this); // handle multi-level types such as Vec>> if (IsBoxedType(stmt->getRangeInit()->getType()) && @@ -1430,7 +1443,6 @@ bool ConverterRefCount::VisitCXXForRangeStmtVector( } ConvertForRangeBody(stmt); - StrCat(token::kCloseCurlyBracket); return false; } @@ -1447,23 +1459,25 @@ bool ConverterRefCount::VisitCXXForRangeStmtString( StrCat(".to_string_iterator() as StringIterator<", ToString(loop_var->getType().getNonReferenceType()), ">"); - StrCat(token::kOpenCurlyBracket); + PushBrace brace(*this); EmitByValueShadow(loop_var_name, loop_var->getType(), loop_var_name + GetPointerDerefSuffix(loop_var->getType()) + ".clone()"); ConvertForRangeBody(stmt); - StrCat(token::kCloseCurlyBracket); return false; } void ConverterRefCount::ConvertArrayCXXConstructExpr( clang::CXXConstructExpr *expr) { - StrCat(std::format("Box::new(std::array::from_fn::<_, {}, _>(|_|", + StrCat("Box::new"); + PushParen outer(*this); + StrCat(std::format("std::array::from_fn::<_, {}, _>", GetArraySize(expr->getType()))); + PushParen inner(*this); + StrCat("|_|"); ConvertCXXConstructExprArgs(expr); - StrCat(token::kCloseParen, token::kCloseParen); } std::string ConverterRefCount::ConvertStream(clang::Expr *expr) { @@ -1703,9 +1717,7 @@ void ConverterRefCount::ConvertAssignment(clang::Expr *lhs, clang::Expr *rhs, std::string_view assign_operator) { auto rhs_as_string = ConvertFreshRValue(rhs); - if (isRValue()) { - StrCat(token::kOpenCurlyBracket); - } + PushBrace brace(*this, isRValue()); if (MayCauseBorrowMutError(lhs, rhs)) { StrCat(keyword::kLet, "__rhs", token::kAssign, rhs_as_string, @@ -1732,7 +1744,7 @@ void ConverterRefCount::ConvertAssignment(clang::Expr *lhs, clang::Expr *rhs, } if (isRValue()) { - StrCat(token::kSemiColon, ConvertRValue(lhs), token::kCloseCurlyBracket); + StrCat(token::kSemiColon, ConvertRValue(lhs)); } } @@ -1770,11 +1782,10 @@ void ConverterRefCount::ConvertGenericBinaryOperator( return; } - StrCat(token::kOpenParen); + PushParen paren(*this); Convert(lhs); StrCat(opcode); Convert(rhs); - StrCat(token::kCloseParen); } void ConverterRefCount::ConvertUniquePtrDeref( @@ -1814,13 +1825,17 @@ bool ConverterRefCount::ConvertCXXOperatorCallExpr( break; } - if (!isAddrOf()) { - StrCat(token::kOpenParen, GetPointerDerefPrefix(expr->getType())); - } - Convert(expr->getArg(0)); - if (!isAddrOf()) { - StrCat(GetPointerDerefSuffix(expr->getType()), token::kCloseParen); - SetValueFreshness(expr->getType()); + { + bool deref = !isAddrOf(); + PushParen paren(*this, deref); + if (deref) { + StrCat(GetPointerDerefPrefix(expr->getType())); + } + Convert(expr->getArg(0)); + if (deref) { + StrCat(GetPointerDerefSuffix(expr->getType())); + SetValueFreshness(expr->getType()); + } } break; @@ -1857,32 +1872,36 @@ bool ConverterRefCount::ConvertCXXOperatorCallExpr( break; } - if (!isAddrOf()) { - StrCat(token::kOpenParen, GetPointerDerefPrefix(expr->getType())); - } + { + bool deref = !isAddrOf(); + PushParen paren(*this, deref); + if (deref) { + StrCat(GetPointerDerefPrefix(expr->getType())); + } - if (is_inner_boxed && !isObject()) { - StrCat("("); - } + if (is_inner_boxed && !isObject()) { + StrCat("("); + } - PushConversionKind push(*this, ConversionKind::Unboxed); - StrCat(std::format("({} as {}).offset({} as isize)", - ConvertObject(expr->getArg(0)), - ConvertPtrType(expr->getArg(0)->getType()), - ConvertRValue(expr->getArg(1)))); - - if (is_inner_boxed) { - StrCat(GetPointerDerefSuffix(expr->getType()), ".as_pointer()"); - if (!isObject()) { - StrCat(std::format("as Ptr<{}>)", ToString(expr->getType()))); + PushConversionKind push(*this, ConversionKind::Unboxed); + StrCat(std::format("({} as {}).offset({} as isize)", + ConvertObject(expr->getArg(0)), + ConvertPtrType(expr->getArg(0)->getType()), + ConvertRValue(expr->getArg(1)))); + + if (is_inner_boxed) { + StrCat(GetPointerDerefSuffix(expr->getType()), ".as_pointer()"); + if (!isObject()) { + StrCat(std::format("as Ptr<{}>)", ToString(expr->getType()))); + } } - } - if (isAddrOf()) { - computed_expr_type_ = ComputedExprType::FreshPointer; - } else { - StrCat(GetPointerDerefSuffix(expr->getType()), token::kCloseParen); - SetValueFreshness(expr->getType()); + if (isAddrOf()) { + computed_expr_type_ = ComputedExprType::FreshPointer; + } else { + StrCat(GetPointerDerefSuffix(expr->getType())); + SetValueFreshness(expr->getType()); + } } break; } @@ -1914,16 +1933,16 @@ void ConverterRefCount::ConvertArraySubscript(clang::Expr *base, base_arr_ty->getElementType().getTypePtr()); } - if (is_inner_boxed) { - StrCat("("); - } - - StrCat(std::format( - "({} as {}).offset({} as isize)", ToString(base->IgnoreImplicit()), - ConvertPtrType(base->IgnoreImplicit()->getType()), ConvertRValue(idx))); - - if (is_inner_boxed) { - StrCat(GetPointerDerefSuffix(type), ".as_pointer()", token::kCloseParen); + { + PushParen paren(*this, is_inner_boxed); + StrCat(std::format("({} as {}).offset({} as isize)", + ToString(base->IgnoreImplicit()), + ConvertPtrType(base->IgnoreImplicit()->getType()), + ConvertRValue(idx))); + + if (is_inner_boxed) { + StrCat(GetPointerDerefSuffix(type), ".as_pointer()"); + } } computed_expr_type_ = ComputedExprType::FreshPointer; @@ -1960,11 +1979,14 @@ void ConverterRefCount::ConvertPointerSubscript( return; } - if (!isAddrOf()) - StrCat(token::kOpenParen, GetPointerDerefPrefix(expr->getType())); + bool deref = !isAddrOf(); + PushParen paren(*this, deref); + if (deref) { + StrCat(GetPointerDerefPrefix(expr->getType())); + } ConvertPointerOffset(base, idx); - if (!isAddrOf()) { - StrCat(GetPointerDerefSuffix(expr->getType()), token::kCloseParen); + if (deref) { + StrCat(GetPointerDerefSuffix(expr->getType())); SetValueFreshness(expr->getType()); } } @@ -2005,13 +2027,17 @@ void ConverterRefCount::ConvertDeref(clang::Expr *expr) { return; } - if (!isAddrOf()) { - StrCat(token::kOpenParen, GetPointerDerefPrefix(pointee_type)); - } - Convert(expr); - if (!isAddrOf()) { - StrCat(GetPointerDerefSuffix(pointee_type), token::kCloseParen); - SetValueFreshness(expr->getType()); + { + bool deref = !isAddrOf(); + PushParen paren(*this, deref); + if (deref) { + StrCat(GetPointerDerefPrefix(pointee_type)); + } + Convert(expr); + if (deref) { + StrCat(GetPointerDerefSuffix(pointee_type)); + SetValueFreshness(expr->getType()); + } } if (isObject()) { diff --git a/tests/benchmarks/out/unsafe/bfs.rs b/tests/benchmarks/out/unsafe/bfs.rs index a356bb87..6fcf07ca 100644 --- a/tests/benchmarks/out/unsafe/bfs.rs +++ b/tests/benchmarks/out/unsafe/bfs.rs @@ -108,7 +108,6 @@ pub unsafe fn BFS_0(graph: *const Graph, mut start_vertex: u32) -> *mut u32 { head = (*head).next; } } - ::std::mem::drop(Box::from_raw(::std::slice::from_raw_parts_mut( visited, libcc2rs::malloc_usable_size(visited as *mut ::libc::c_void) @@ -170,7 +169,6 @@ unsafe fn main_0() -> i32 { } i.prefix_inc(); } - ::std::mem::drop(Box::from_raw(::std::slice::from_raw_parts_mut( graph.adj, libcc2rs::malloc_usable_size(graph.adj as *mut ::libc::c_void) diff --git a/tests/unit/out/unsafe/memset.rs b/tests/unit/out/unsafe/memset.rs index 7693cffb..9ffab275 100644 --- a/tests/unit/out/unsafe/memset.rs +++ b/tests/unit/out/unsafe/memset.rs @@ -28,7 +28,6 @@ unsafe fn main_0() -> i32 { sum += (*arr.offset((i) as isize)); i.prefix_inc(); } - ::std::mem::drop(Box::from_raw(::std::slice::from_raw_parts_mut( arr, libcc2rs::malloc_usable_size(arr as *mut ::libc::c_void) / ::std::mem::size_of::(),