Skip to content

Commit 0a98dc0

Browse files
committed
Remove bottom-up IsRedundantCopyInConversion with top-down PushSuppressIteratorClone
1 parent 09ee4cd commit 0a98dc0

5 files changed

Lines changed: 45 additions & 33 deletions

File tree

cpp2rust/converter/converter.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2757,6 +2757,8 @@ void Converter::ConvertCXXConstructExprArgs(clang::CXXConstructExpr *expr) {
27572757
}
27582758

27592759
bool Converter::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) {
2760+
PushSuppressIteratorClone push(*this, expr);
2761+
27602762
if (auto str = GetMappedAsString(expr, expr->getArgs(), expr->getNumArgs());
27612763
!str.empty()) {
27622764
StrCat(str);
@@ -2767,8 +2769,10 @@ bool Converter::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) {
27672769
if (ctor->isCopyOrMoveConstructor() ||
27682770
(ctor->isConvertingConstructor(false) && ctor->getNumParams() == 1 &&
27692771
ctor->getParamDecl(0)->getType()->isRValueReferenceType())) {
2772+
// Take supress before recursing into the child.
2773+
bool suppress = PushSuppressIteratorClone::take(*this, expr);
27702774
Convert(expr->getArg(0));
2771-
if (ctor->isCopyConstructor() && !IsRedundantCopyInConversion(ctx_, expr)) {
2775+
if (ctor->isCopyConstructor() && !suppress) {
27722776
StrCat(".clone()");
27732777
}
27742778
return false;

cpp2rust/converter/converter.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
529529
bool in_function_formals_ = false;
530530
bool in_const_initializer_ = false;
531531
std::optional<bool> autoref_mut_;
532+
bool suppress_iterator_clone_ = false;
532533

533534
struct PushExplicitAutoref {
534535
Converter &c;
@@ -540,6 +541,43 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
540541
~PushExplicitAutoref() { c.autoref_mut_ = prev; }
541542
};
542543

544+
struct PushSuppressIteratorClone {
545+
Converter &c;
546+
bool prev;
547+
PushSuppressIteratorClone(Converter &c, clang::CXXConstructExpr *expr)
548+
: c(c), prev(c.suppress_iterator_clone_) {
549+
auto *ctor = expr->getConstructor();
550+
if (ctor->isConvertingConstructor(/*AllowExplicit=*/false) &&
551+
ctor->getNumParams() == 1 && IsIteratorType(expr->getType())) {
552+
c.suppress_iterator_clone_ = true;
553+
}
554+
}
555+
~PushSuppressIteratorClone() { c.suppress_iterator_clone_ = prev; }
556+
PushSuppressIteratorClone(const PushSuppressIteratorClone &) = delete;
557+
PushSuppressIteratorClone &
558+
operator=(const PushSuppressIteratorClone &) = delete;
559+
560+
static bool take(Converter &c, clang::CXXConstructExpr *inner) {
561+
bool suppress =
562+
c.suppress_iterator_clone_ && IsIteratorType(inner->getType());
563+
c.suppress_iterator_clone_ = false;
564+
return suppress;
565+
}
566+
567+
private:
568+
static bool IsIteratorType(clang::QualType qt) {
569+
if (auto *record = qt->getAsCXXRecordDecl()) {
570+
for (auto *d : record->decls()) {
571+
if (auto *tnd = llvm::dyn_cast<clang::TypedefNameDecl>(d)) {
572+
if (tnd->getName() == "iterator_category")
573+
return true;
574+
}
575+
}
576+
}
577+
return false;
578+
}
579+
};
580+
543581
struct PushConstInitializer {
544582
Converter &c;
545583
bool prev;

cpp2rust/converter/converter_lib.cpp

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -644,34 +644,6 @@ std::string GetClassName(clang::QualType type) {
644644
return {};
645645
}
646646

647-
static bool IsIteratorType(clang::QualType qt) {
648-
if (auto *record = qt->getAsCXXRecordDecl()) {
649-
for (auto *d : record->decls()) {
650-
if (auto *tnd = llvm::dyn_cast<clang::TypedefNameDecl>(d)) {
651-
if (tnd->getName() == "iterator_category")
652-
return true;
653-
}
654-
}
655-
}
656-
return false;
657-
}
658-
659-
bool IsRedundantCopyInConversion(clang::ASTContext &ctx,
660-
const clang::CXXConstructExpr *expr) {
661-
return false;
662-
if (auto parents = ctx.getParentMapContext().getParents(*expr);
663-
!parents.empty()) {
664-
if (auto *parent = parents[0].get<clang::CXXConstructExpr>()) {
665-
if (parent->getConstructor()->isConvertingConstructor(
666-
/* AllowExplicit= */ false)) {
667-
return IsIteratorType(expr->getType()) &&
668-
IsIteratorType(parent->getType());
669-
}
670-
}
671-
}
672-
return false;
673-
}
674-
675647
bool IsVaListType(clang::QualType type) {
676648
for (auto t = type; !t.isNull();) {
677649
if (auto *adjusted = t->getAs<clang::AdjustedType>()) {

cpp2rust/converter/converter_lib.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,6 @@ GetForRangeIteratorType(const clang::CXXForRangeStmt *for_range);
145145

146146
std::string GetClassName(clang::QualType type);
147147

148-
bool IsRedundantCopyInConversion(clang::ASTContext &ctx,
149-
const clang::CXXConstructExpr *expr);
150-
151148
bool IsVaListType(clang::QualType type);
152149

153150
bool IsBuiltinVaStart(const clang::CallExpr *expr);

cpp2rust/converter/models/converter_refcount.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1541,6 +1541,7 @@ std::string ConverterRefCount::ConvertStream(clang::Expr *expr) {
15411541

15421542
bool ConverterRefCount::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) {
15431543
PushConversionKind push(*this, ConversionKind::Unboxed);
1544+
PushSuppressIteratorClone push_suppress(*this, expr);
15441545

15451546
if (auto str = GetMappedAsString(expr, expr->getArgs(), expr->getNumArgs());
15461547
!str.empty()) {
@@ -1564,7 +1565,7 @@ bool ConverterRefCount::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) {
15641565
}
15651566

15661567
if (ctor->isCopyConstructor()) {
1567-
StrCat(IsRedundantCopyInConversion(ctx_, expr)
1568+
StrCat(PushSuppressIteratorClone::take(*this, expr)
15681569
? ConvertRValue(expr->getArg(0))
15691570
: ConvertFreshRValue(expr->getArg(0)));
15701571
return false;

0 commit comments

Comments
 (0)