@@ -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;
0 commit comments