@@ -86,6 +86,16 @@ static bool isConcreteAndValid(ProtocolConformanceRef conformanceRef,
86
86
});
87
87
}
88
88
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
+
89
99
static clang::TypeDecl *
90
100
getIteratorCategoryDecl (const clang::CXXRecordDecl *clangDecl) {
91
101
clang::IdentifierInfo *iteratorCategoryDeclName =
@@ -380,6 +390,38 @@ void swift::conformToCxxIteratorIfNeeded(
380
390
decl, {KnownProtocolKind::UnsafeCxxRandomAccessIterator});
381
391
}
382
392
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
+
383
425
void swift::conformToCxxSequenceIfNeeded (
384
426
ClangImporter::Implementation &impl, NominalTypeDecl *decl,
385
427
const clang::CXXRecordDecl *clangDecl) {
@@ -522,16 +564,6 @@ void swift::conformToCxxSequenceIfNeeded(
522
564
}
523
565
}
524
566
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
-
535
567
void swift::conformToCxxSetIfNeeded (ClangImporter::Implementation &impl,
536
568
NominalTypeDecl *decl,
537
569
const clang::CXXRecordDecl *clangDecl) {
0 commit comments