@@ -927,3 +927,47 @@ void swift::conformToCxxDictionaryIfNeeded(
927927 insert->getResultInterfaceType ());
928928 impl.addSynthesizedProtocolAttrs (decl, {KnownProtocolKind::CxxDictionary});
929929}
930+
931+ void swift::conformToCxxVectorIfNeeded (ClangImporter::Implementation &impl,
932+ NominalTypeDecl *decl,
933+ const clang::CXXRecordDecl *clangDecl) {
934+ PrettyStackTraceDecl trace (" conforming to CxxVector" , decl);
935+
936+ assert (decl);
937+ assert (clangDecl);
938+ ASTContext &ctx = decl->getASTContext ();
939+
940+ // Only auto-conform types from the C++ standard library. Custom user types
941+ // might have a similar interface but different semantics.
942+ if (!isStdDecl (clangDecl, {" vector" }))
943+ return ;
944+
945+ auto valueType = lookupDirectSingleWithoutExtensions<TypeAliasDecl>(
946+ decl, ctx.getIdentifier (" value_type" ));
947+ auto iterType = lookupDirectSingleWithoutExtensions<TypeAliasDecl>(
948+ decl, ctx.getIdentifier (" const_iterator" ));
949+ if (!valueType || !iterType)
950+ return ;
951+
952+ ProtocolDecl *cxxRandomAccessIteratorProto =
953+ ctx.getProtocol (KnownProtocolKind::UnsafeCxxRandomAccessIterator);
954+ if (!cxxRandomAccessIteratorProto)
955+ return ;
956+
957+ auto rawIteratorTy = iterType->getUnderlyingType ();
958+
959+ // Check if RawIterator conforms to UnsafeCxxRandomAccessIterator.
960+ ModuleDecl *module = decl->getModuleContext ();
961+ auto rawIteratorConformanceRef =
962+ module ->lookupConformance (rawIteratorTy, cxxRandomAccessIteratorProto);
963+ if (!isConcreteAndValid (rawIteratorConformanceRef, module ))
964+ return ;
965+
966+ impl.addSynthesizedTypealias (decl, ctx.Id_Element ,
967+ valueType->getUnderlyingType ());
968+ impl.addSynthesizedTypealias (decl, ctx.Id_ArrayLiteralElement ,
969+ valueType->getUnderlyingType ());
970+ impl.addSynthesizedTypealias (decl, ctx.getIdentifier (" RawIterator" ),
971+ rawIteratorTy);
972+ impl.addSynthesizedProtocolAttrs (decl, {KnownProtocolKind::CxxVector});
973+ }
0 commit comments