Skip to content

Commit 8981e9e

Browse files
Copilotnunoplopes
andcommitted
perf: eliminate spurious string copies in cpp2rust converter
- mapper.cpp: use std::move() when passing local strings to normalizeTranslationRule() to avoid unnecessary copies in ToString() - converter.cpp recordDerivesCopy: cache Mapper::Map(f->getType()) result to avoid calling it twice per field - converter.cpp GetDefaultAsString: cache Mapper::ToString(qual_type) result to avoid calling it twice in successive else-if branches - converter.cpp EmitRustStruct/VisitCXXRecordDecl: replace std::string(keyword::kImpl) + ' ' + name with std::format to avoid constructing multiple temporary strings - converter_lib.cpp GetFileName: construct std::filesystem::path directly from StringRef iterators, eliminating the intermediate file_name_as_string copy and reusing file_path.string() as fallback Agent-Logs-Url: https://github.com/Cpp2Rust/cpp2rust/sessions/b538d15a-35a7-4c43-93f3-6621eabaf105 Co-authored-by: nunoplopes <2998477+nunoplopes@users.noreply.github.com>
1 parent 56dc655 commit 8981e9e

4 files changed

Lines changed: 47 additions & 44 deletions

File tree

cpp2rust/converter/converter.cpp

Lines changed: 41 additions & 37 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
}
@@ -2785,40 +2786,43 @@ std::string Converter::GetDefaultAsString(clang::QualType qual_type) {
27852786
} else if (auto *array_type =
27862787
clang::dyn_cast<clang::IncompleteArrayType>(qual_type)) {
27872788
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);
28202789
} else {
2821-
return GetDefaultAsStringFallback(qual_type);
2790+
auto qual_type_str = Mapper::ToString(qual_type);
2791+
if (qual_type_str == "struct std::pair") {
2792+
auto template_args = *GetTemplateArgs(qual_type);
2793+
auto first_type = template_args[0].getAsType();
2794+
auto second_type = template_args[1].getAsType();
2795+
return std::format("({}, {})", GetDefaultAsString(first_type),
2796+
GetDefaultAsString(second_type));
2797+
} else if (qual_type_str.contains("std::array")) {
2798+
assert(GetTemplateArgs(qual_type).has_value());
2799+
auto template_args = *GetTemplateArgs(qual_type);
2800+
assert(template_args.size() == 2);
2801+
auto array_size = template_args[1];
2802+
unsigned size = 0;
2803+
switch (array_size.getKind()) {
2804+
case clang::TemplateArgument::Expression: {
2805+
auto array_size_expr = array_size.getAsExpr();
2806+
assert(array_size_expr && !array_size_expr->isValueDependent());
2807+
clang::Expr::EvalResult result;
2808+
ENSURE(array_size_expr->EvaluateAsInt(result, ctx_));
2809+
size = result.Val.getInt().getZExtValue();
2810+
break;
2811+
}
2812+
case clang::TemplateArgument::Integral: {
2813+
size = array_size.getAsIntegral().getZExtValue();
2814+
break;
2815+
}
2816+
default:
2817+
assert(0 && "Unsupported array size kind");
2818+
break;
2819+
}
2820+
return std::format(
2821+
"std::array::from_fn::<_, {}, _>(|_| Default::default()).to_vec()",
2822+
size);
2823+
} else {
2824+
return GetDefaultAsStringFallback(qual_type);
2825+
}
28222826
}
28232827
}
28242828

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: 2 additions & 2 deletions
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 = '.';
@@ -22,7 +22,7 @@ inline constexpr const char *kDiff = "!=";
2222
inline constexpr char kZero = '0';
2323
inline constexpr char kOne = '1';
2424
inline constexpr char kRef = '&';
25-
inline constexpr const char *kStar = "*";
25+
inline constexpr char kStar = '*';
2626
inline constexpr const char *kArrow = "->";
2727
inline constexpr char kHash = '#';
2828
inline constexpr char kMinus = '-';

cpp2rust/converter/mapper.cpp

Lines changed: 2 additions & 2 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()) << " ";

0 commit comments

Comments
 (0)