@@ -409,7 +409,10 @@ writeImports(raw_ostream &out, llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
409
409
const FrontendOptions &frontendOpts,
410
410
clang::HeaderSearch &clangHeaderSearchInfo,
411
411
const llvm::StringMap<StringRef> &exposedModuleHeaderNames,
412
- bool useCxxImport = false ) {
412
+ bool useCxxImport = false ,
413
+ bool useNonModularIncludes = false ) {
414
+ useNonModularIncludes |= frontendOpts.EmitClangHeaderWithNonModularIncludes ;
415
+
413
416
// Note: we can't use has_feature(modules) as it's always enabled in C++20
414
417
// mode.
415
418
out << " #if __has_feature(objc_modules)\n " ;
@@ -446,7 +449,7 @@ writeImports(raw_ostream &out, llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
446
449
llvm::vfs::FileSystem &fileSystem = fileManager.getVirtualFileSystem ();
447
450
llvm::ErrorOr<std::string> cwd = fileSystem.getCurrentWorkingDirectory ();
448
451
449
- if (frontendOpts. EmitClangHeaderWithNonModularIncludes ) {
452
+ if (useNonModularIncludes ) {
450
453
assert (cwd && " Access to current working directory required" );
451
454
452
455
for (auto searchDir = clangHeaderSearchInfo.search_dir_begin ();
@@ -498,7 +501,7 @@ writeImports(raw_ostream &out, llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
498
501
}
499
502
if (seenImports.insert (Name).second ) {
500
503
out << importDirective << ' ' << Name.str () << importDirectiveLineEnd;
501
- if (frontendOpts. EmitClangHeaderWithNonModularIncludes ) {
504
+ if (useNonModularIncludes ) {
502
505
if (const clang::Module *underlyingClangModule =
503
506
swiftModule->findUnderlyingClangModule ()) {
504
507
collectClangModuleHeaderIncludes (
@@ -521,19 +524,21 @@ writeImports(raw_ostream &out, llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
521
524
out << importDirective << ' ' ;
522
525
ModuleDecl::ReverseFullNameIterator (clangModule).printForward (out);
523
526
out << importDirectiveLineEnd;
524
- if (frontendOpts. EmitClangHeaderWithNonModularIncludes ) {
527
+ if (useNonModularIncludes ) {
525
528
collectClangModuleHeaderIncludes (
526
529
clangModule, fileManager, requiredTextualIncludes, visitedModules,
527
530
includeDirs, cwd.get ());
528
531
}
529
532
}
530
533
}
531
534
532
- if (frontendOpts. EmitClangHeaderWithNonModularIncludes ) {
533
- out << " #else \n " ;
534
- for (auto header : requiredTextualIncludes) {
535
+ if (useNonModularIncludes && !requiredTextualIncludes. empty () ) {
536
+ out << " #elif defined(__OBJC__) \n " ;
537
+ for (auto header : requiredTextualIncludes)
535
538
out << " #import <" << header << " >\n " ;
536
- }
539
+ out << " #else\n " ;
540
+ for (auto header : requiredTextualIncludes)
541
+ out << " #include <" << header << " >\n " ;
537
542
}
538
543
out << " #endif\n\n " ;
539
544
for (const auto header : textualIncludes) {
@@ -544,8 +549,13 @@ writeImports(raw_ostream &out, llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
544
549
if (bridgingHeader.empty ())
545
550
out << " #import <" << M.getName ().str () << ' /' << M.getName ().str ()
546
551
<< " .h>\n\n " ;
547
- else
548
- out << " #import \" " << bridgingHeader << " \"\n\n " ;
552
+ else {
553
+ out << " #if defined(__OBJC__)\n " ;
554
+ out << " #import \" " << bridgingHeader << " \"\n " ;
555
+ out << " #else\n " ;
556
+ out << " #include \" " << bridgingHeader << " \"\n " ;
557
+ out << " #endif\n\n " ;
558
+ }
549
559
}
550
560
}
551
561
@@ -606,17 +616,24 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
606
616
writePrologue (os, M->getASTContext (), computeMacroGuard (M));
607
617
608
618
// C content (@cdecl)
619
+ std::string moduleContentsScratch;
609
620
if (M->getASTContext ().LangOpts .hasFeature (Feature::CDecl)) {
610
621
SmallPtrSet<ImportModuleTy, 8 > imports;
611
- emitExternC (os, [&] {
612
- printModuleContentsAsC (os, imports, *M, interopContext);
613
- });
622
+ llvm::raw_string_ostream cModuleContents{moduleContentsScratch};
623
+ printModuleContentsAsC (cModuleContents, imports, *M, interopContext);
624
+
625
+ llvm::StringMap<StringRef> exposedModuleHeaderNames;
626
+ writeImports (os, imports, *M, bridgingHeader, frontendOpts,
627
+ clangHeaderSearchInfo, exposedModuleHeaderNames,
628
+ /* useCxxImport=*/ false , /* useNonModularIncludes*/ true );
629
+
630
+ emitExternC (os, [&] { os << " \n " << cModuleContents.str (); });
631
+ moduleContentsScratch.clear ();
614
632
}
615
633
616
634
// Objective-C content
617
635
SmallPtrSet<ImportModuleTy, 8 > imports;
618
- std::string objcModuleContentsBuf;
619
- llvm::raw_string_ostream objcModuleContents{objcModuleContentsBuf};
636
+ llvm::raw_string_ostream objcModuleContents{moduleContentsScratch};
620
637
printModuleContentsAsObjC (objcModuleContents, imports, *M, interopContext);
621
638
emitObjCConditional (os, [&] {
622
639
llvm::StringMap<StringRef> exposedModuleHeaderNames;
0 commit comments