Skip to content

Commit 9a3bdee

Browse files
Copilotnunoplopes
andauthored
Eliminate spurious string copies (#35)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Nuno Lopes <nuno.lopes@tecnico.ulisboa.pt>
1 parent a0dcdd7 commit 9a3bdee

5 files changed

Lines changed: 57 additions & 51 deletions

File tree

cpp2rust/converter/converter.cpp

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -552,15 +552,16 @@ static bool recordDerivesCopy(const clang::RecordDecl *decl) {
552552
for (auto f : decl->fields()) {
553553
// Records that contain std::vector, std::array, std::string or anything
554554
// that is translated to Vec<>, do not derive Copy
555-
if (Mapper::Map(f->getType()).starts_with("Vec<")) {
555+
auto mapped = Mapper::Map(f->getType());
556+
if (mapped.starts_with("Vec<")) {
556557
return false;
557558
}
558559

559560
if (IsUniquePtr(f->getType())) {
560561
return false;
561562
}
562563

563-
if (Mapper::Map(f->getType()).starts_with("BTreeMap<")) {
564+
if (mapped.starts_with("BTreeMap<")) {
564565
return false;
565566
}
566567

@@ -653,7 +654,7 @@ void Converter::EmitRustStruct(clang::RecordDecl *decl) {
653654
auto struct_name = GetRecordName(cxx);
654655

655656
ConvertCXXMethodDecls(
656-
cxx, std::string(keyword::kImpl) + ' ' + struct_name,
657+
cxx, std::format("{} {}", keyword::kImpl, struct_name),
657658
[](const auto *method) {
658659
return !method->isImplicit() &&
659660
!(method->getDefinition() &&
@@ -701,7 +702,7 @@ bool Converter::VisitCXXRecordDecl(clang::CXXRecordDecl *decl) {
701702
if (decl->isStruct() || decl->isClass()) {
702703
for (auto c : GetTemplateInstantiatedCtors(decl)) {
703704
if (!decl_ids_.contains(GetID(c))) {
704-
StrCat(std::string(keyword::kImpl) + ' ' + GetRecordName(decl));
705+
StrCat(keyword::kImpl, GetRecordName(decl));
705706
PushBrace brace(*this);
706707
VisitCXXMethodDecl(c);
707708
}
@@ -1875,7 +1876,7 @@ bool Converter::VisitBinaryOperator(clang::BinaryOperator *expr) {
18751876
auto *rhs = expr->getRHS();
18761877
auto lhs_type = lhs->getType();
18771878
auto rhs_type = rhs->getType();
1878-
std::string opcode_as_string = expr->getOpcodeStr().str();
1879+
std::string_view opcode_as_string = expr->getOpcodeStr();
18791880

18801881
if (auto *cmpd_assign_op =
18811882
llvm::dyn_cast<clang::CompoundAssignOperator>(expr);
@@ -1901,7 +1902,9 @@ bool Converter::VisitBinaryOperator(clang::BinaryOperator *expr) {
19011902
Convert(lhs);
19021903
ConvertCast(computation_result_type);
19031904
}
1904-
StrCat(std::regex_replace(opcode_as_string, std::regex("="), ""));
1905+
std::string op(opcode_as_string);
1906+
op.erase(std::remove(op.begin(), op.end(), '='), op.end());
1907+
StrCat(op);
19051908
Convert(rhs);
19061909
}
19071910
if (lhs_type->isBooleanType()) {
@@ -2206,7 +2209,7 @@ bool Converter::VisitParenExpr(clang::ParenExpr *expr) {
22062209
bool Converter::ConvertCXXOperatorCallExpr(clang::CXXOperatorCallExpr *expr) {
22072210
switch (expr->getOperator()) {
22082211
case clang::OverloadedOperatorKind::OO_Equal:
2209-
ConvertAssignment(expr->getArg(0), expr->getArg(1), token::kAssign);
2212+
ConvertAssignment(expr->getArg(0), expr->getArg(1), "=");
22102213
break;
22112214
case clang::OverloadedOperatorKind::OO_Star:
22122215
case clang::OverloadedOperatorKind::OO_Arrow:
@@ -2785,40 +2788,43 @@ std::string Converter::GetDefaultAsString(clang::QualType qual_type) {
27852788
} else if (auto *array_type =
27862789
clang::dyn_cast<clang::IncompleteArrayType>(qual_type)) {
27872790
return GetDefaultAsString(array_type->getElementType());
2788-
} else if (Mapper::ToString(qual_type) == "struct std::pair") {
2789-
auto template_args = *GetTemplateArgs(qual_type);
2790-
auto first_type = template_args[0].getAsType();
2791-
auto second_type = template_args[1].getAsType();
2792-
return std::format("({}, {})", GetDefaultAsString(first_type),
2793-
GetDefaultAsString(second_type));
2794-
} else if (Mapper::ToString(qual_type).contains("std::array")) {
2795-
assert(GetTemplateArgs(qual_type).has_value());
2796-
auto template_args = *GetTemplateArgs(qual_type);
2797-
assert(template_args.size() == 2);
2798-
auto array_size = template_args[1];
2799-
unsigned size = 0;
2800-
switch (array_size.getKind()) {
2801-
case clang::TemplateArgument::Expression: {
2802-
auto array_size_expr = array_size.getAsExpr();
2803-
assert(array_size_expr && !array_size_expr->isValueDependent());
2804-
clang::Expr::EvalResult result;
2805-
ENSURE(array_size_expr->EvaluateAsInt(result, ctx_));
2806-
size = result.Val.getInt().getZExtValue();
2807-
break;
2808-
}
2809-
case clang::TemplateArgument::Integral: {
2810-
size = array_size.getAsIntegral().getZExtValue();
2811-
break;
2812-
}
2813-
default:
2814-
assert(0 && "Unsupported array size kind");
2815-
break;
2816-
}
2817-
return std::format(
2818-
"std::array::from_fn::<_, {}, _>(|_| Default::default()).to_vec()",
2819-
size);
28202791
} else {
2821-
return GetDefaultAsStringFallback(qual_type);
2792+
auto qual_type_str = Mapper::ToString(qual_type);
2793+
if (qual_type_str == "struct std::pair") {
2794+
auto template_args = *GetTemplateArgs(qual_type);
2795+
auto first_type = template_args[0].getAsType();
2796+
auto second_type = template_args[1].getAsType();
2797+
return std::format("({}, {})", GetDefaultAsString(first_type),
2798+
GetDefaultAsString(second_type));
2799+
} else if (qual_type_str.contains("std::array")) {
2800+
assert(GetTemplateArgs(qual_type).has_value());
2801+
auto template_args = *GetTemplateArgs(qual_type);
2802+
assert(template_args.size() == 2);
2803+
auto array_size = template_args[1];
2804+
unsigned size = 0;
2805+
switch (array_size.getKind()) {
2806+
case clang::TemplateArgument::Expression: {
2807+
auto array_size_expr = array_size.getAsExpr();
2808+
assert(array_size_expr && !array_size_expr->isValueDependent());
2809+
clang::Expr::EvalResult result;
2810+
ENSURE(array_size_expr->EvaluateAsInt(result, ctx_));
2811+
size = result.Val.getInt().getZExtValue();
2812+
break;
2813+
}
2814+
case clang::TemplateArgument::Integral: {
2815+
size = array_size.getAsIntegral().getZExtValue();
2816+
break;
2817+
}
2818+
default:
2819+
assert(0 && "Unsupported array size kind");
2820+
break;
2821+
}
2822+
return std::format(
2823+
"std::array::from_fn::<_, {}, _>(|_| Default::default()).to_vec()",
2824+
size);
2825+
} else {
2826+
return GetDefaultAsStringFallback(qual_type);
2827+
}
28222828
}
28232829
}
28242830

cpp2rust/converter/converter_lib.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,11 +268,10 @@ std::string GetFileName(const clang::Decl *decl) {
268268
const auto &ctx = decl->getASTContext();
269269
const auto full_location = ctx.getFullLoc(decl->getBeginLoc());
270270
const auto file_name = ctx.getSourceManager().getFilename(full_location);
271-
const auto file_name_as_string = file_name.str();
272-
const std::filesystem::path file_path(file_name_as_string);
271+
const std::filesystem::path file_path(file_name.begin(), file_name.end());
273272
return std::filesystem::exists(file_path)
274273
? std::filesystem::canonical(file_path).string()
275-
: file_name_as_string;
274+
: file_path.string();
276275
}
277276

278277
unsigned GetLineNumber(const clang::Decl *decl) {

cpp2rust/converter/lex.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ inline constexpr const char *kSemiColon = ";\n";
1313
inline constexpr char kComma = ',';
1414
inline constexpr char kColon = ':';
1515
inline constexpr const char *kDoubleColon = "::";
16-
inline constexpr const char *kAssign = "=";
16+
inline constexpr char kAssign = '=';
1717
inline constexpr char kOpenParen = '(';
1818
inline constexpr char kCloseParen = ')';
1919
inline constexpr char kDot = '.';

cpp2rust/converter/mapper.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ std::string ToString(clang::QualType qual_type) {
732732
std::string type;
733733
llvm::raw_string_ostream os(type);
734734
normalizeQualType(qual_type).print(os, getPrintPolicy());
735-
return normalizeTranslationRule(type);
735+
return normalizeTranslationRule(std::move(type));
736736
}
737737

738738
std::string ToString(const clang::NamedDecl *decl) {
@@ -753,7 +753,7 @@ std::string ToString(const clang::NamedDecl *decl) {
753753

754754
if (!func_decl) {
755755
decl->printQualifiedName(os, getPrintPolicy());
756-
return normalizeTranslationRule(out);
756+
return normalizeTranslationRule(std::move(out));
757757
}
758758

759759
os << ToString(func_decl->getReturnType()) << " ";
@@ -798,7 +798,7 @@ std::string ToString(const clang::NamedDecl *decl) {
798798
}
799799
}
800800

801-
return normalizeTranslationRule(os.str());
801+
return normalizeTranslationRule(std::move(out));
802802
}
803803

804804
std::string ToString(const clang::Expr *expr) {

cpp2rust/converter/models/converter_refcount.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include <clang/Basic/OperatorKinds.h>
77

88
#include <format>
9-
#include <regex>
109

1110
#include "compiler.h"
1211
#include "converter/converter_lib.h"
@@ -1144,7 +1143,7 @@ bool ConverterRefCount::VisitBinaryOperator(clang::BinaryOperator *expr) {
11441143
auto *rhs = expr->getRHS();
11451144
auto lhs_type = lhs->getType();
11461145
auto rhs_type = rhs->getType();
1147-
std::string opcode_as_string = expr->getOpcodeStr().str();
1146+
std::string_view opcode_as_string = expr->getOpcodeStr();
11481147

11491148
if (auto *assign = llvm::dyn_cast<clang::CompoundAssignOperator>(expr);
11501149
assign && lhs_type != assign->getComputationResultType()) {
@@ -1165,7 +1164,9 @@ bool ConverterRefCount::VisitBinaryOperator(clang::BinaryOperator *expr) {
11651164
StrCat(ConvertRValue(lhs));
11661165
ConvertCast(computation_result_type);
11671166
}
1168-
StrCat(std::regex_replace(opcode_as_string, std::regex("="), ""));
1167+
std::string op(opcode_as_string);
1168+
op.erase(std::remove(op.begin(), op.end(), '='), op.end());
1169+
StrCat(op);
11691170
Convert(rhs);
11701171
}
11711172
if (lhs_type->isBooleanType()) {
@@ -1805,7 +1806,7 @@ bool ConverterRefCount::ConvertCXXOperatorCallExpr(
18051806
clang::CXXOperatorCallExpr *expr) {
18061807
switch (expr->getOperator()) {
18071808
case clang::OverloadedOperatorKind::OO_Equal:
1808-
ConvertAssignment(expr->getArg(0), expr->getArg(1), token::kAssign);
1809+
ConvertAssignment(expr->getArg(0), expr->getArg(1), "=");
18091810
break;
18101811

18111812
case clang::OverloadedOperatorKind::OO_Arrow:

0 commit comments

Comments
 (0)