@@ -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 =
@@ -380,6 +390,38 @@ void swift::conformToCxxIteratorIfNeeded(
380390 decl, {KnownProtocolKind::UnsafeCxxRandomAccessIterator});
381391}
382392
393+ void swift::conformToCxxOptionalIfNeeded (
394+ ClangImporter::Implementation &impl, NominalTypeDecl *decl,
395+ const clang::CXXRecordDecl *clangDecl) {
396+ PrettyStackTraceDecl trace (" conforming to CxxOptional" , decl);
397+
398+ assert (decl);
399+ assert (clangDecl);
400+ ASTContext &ctx = decl->getASTContext ();
401+
402+ if (!isStdDecl (clangDecl, {" optional" }))
403+ return ;
404+
405+ ProtocolDecl *cxxOptionalProto =
406+ ctx.getProtocol (KnownProtocolKind::CxxOptional);
407+ // If the Cxx module is missing, or does not include one of the necessary
408+ // protocol, bail.
409+ if (!cxxOptionalProto)
410+ return ;
411+
412+ auto pointeeId = ctx.getIdentifier (" pointee" );
413+ auto pointees = lookupDirectWithoutExtensions (decl, pointeeId);
414+ if (pointees.size () != 1 )
415+ return ;
416+ auto pointee = dyn_cast<VarDecl>(pointees.front ());
417+ if (!pointee)
418+ return ;
419+ auto pointeeTy = pointee->getInterfaceType ();
420+
421+ impl.addSynthesizedTypealias (decl, ctx.getIdentifier (" Wrapped" ), pointeeTy);
422+ impl.addSynthesizedProtocolAttrs (decl, {KnownProtocolKind::CxxOptional});
423+ }
424+
383425void swift::conformToCxxSequenceIfNeeded (
384426 ClangImporter::Implementation &impl, NominalTypeDecl *decl,
385427 const clang::CXXRecordDecl *clangDecl) {
@@ -522,16 +564,6 @@ void swift::conformToCxxSequenceIfNeeded(
522564 }
523565}
524566
525- static bool isStdDecl (const clang::CXXRecordDecl *clangDecl,
526- llvm::ArrayRef<StringRef> names) {
527- if (!clangDecl->isInStdNamespace ())
528- return false ;
529- if (!clangDecl->getIdentifier ())
530- return false ;
531- StringRef name = clangDecl->getName ();
532- return llvm::is_contained (names, name);
533- }
534-
535567void swift::conformToCxxSetIfNeeded (ClangImporter::Implementation &impl,
536568 NominalTypeDecl *decl,
537569 const clang::CXXRecordDecl *clangDecl) {
0 commit comments