@@ -86,6 +86,16 @@ static bool isConcreteAndValid(ProtocolConformanceRef conformanceRef,
8686 });
8787}
8888
89+ static bool isStdDecl (const clang::CXXRecordDecl *clangDecl,
90+ llvm::ArrayRef<StringRef> names) {
91+ if (!clangDecl->isInStdNamespace ())
92+ return false ;
93+ if (!clangDecl->getIdentifier ())
94+ return false ;
95+ StringRef name = clangDecl->getName ();
96+ return llvm::is_contained (names, name);
97+ }
98+
8999static clang::TypeDecl *
90100getIteratorCategoryDecl (const clang::CXXRecordDecl *clangDecl) {
91101 clang::IdentifierInfo *iteratorCategoryDeclName =
@@ -381,6 +391,38 @@ void swift::conformToCxxIteratorIfNeeded(
381391 decl, {KnownProtocolKind::UnsafeCxxRandomAccessIterator});
382392}
383393
394+ void swift::conformToCxxOptionalIfNeeded (
395+ ClangImporter::Implementation &impl, NominalTypeDecl *decl,
396+ const clang::CXXRecordDecl *clangDecl) {
397+ PrettyStackTraceDecl trace (" conforming to CxxOptional" , decl);
398+
399+ assert (decl);
400+ assert (clangDecl);
401+ ASTContext &ctx = decl->getASTContext ();
402+
403+ if (!isStdDecl (clangDecl, {" optional" }))
404+ return ;
405+
406+ ProtocolDecl *cxxOptionalProto =
407+ ctx.getProtocol (KnownProtocolKind::CxxOptional);
408+ // If the Cxx module is missing, or does not include one of the necessary
409+ // protocol, bail.
410+ if (!cxxOptionalProto)
411+ return ;
412+
413+ auto pointeeId = ctx.getIdentifier (" pointee" );
414+ auto pointees = lookupDirectWithoutExtensions (decl, pointeeId);
415+ if (pointees.size () != 1 )
416+ return ;
417+ auto pointee = dyn_cast<VarDecl>(pointees.front ());
418+ if (!pointee)
419+ return ;
420+ auto pointeeTy = pointee->getInterfaceType ();
421+
422+ impl.addSynthesizedTypealias (decl, ctx.getIdentifier (" Wrapped" ), pointeeTy);
423+ impl.addSynthesizedProtocolAttrs (decl, {KnownProtocolKind::CxxOptional});
424+ }
425+
384426void swift::conformToCxxSequenceIfNeeded (
385427 ClangImporter::Implementation &impl, NominalTypeDecl *decl,
386428 const clang::CXXRecordDecl *clangDecl) {
@@ -523,16 +565,6 @@ void swift::conformToCxxSequenceIfNeeded(
523565 }
524566}
525567
526- static bool isStdDecl (const clang::CXXRecordDecl *clangDecl,
527- llvm::ArrayRef<StringRef> names) {
528- if (!clangDecl->isInStdNamespace ())
529- return false ;
530- if (!clangDecl->getIdentifier ())
531- return false ;
532- StringRef name = clangDecl->getName ();
533- return llvm::is_contained (names, name);
534- }
535-
536568void swift::conformToCxxSetIfNeeded (ClangImporter::Implementation &impl,
537569 NominalTypeDecl *decl,
538570 const clang::CXXRecordDecl *clangDecl) {
0 commit comments