@@ -409,7 +409,10 @@ writeImports(raw_ostream &out, llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
409409 const FrontendOptions &frontendOpts,
410410 clang::HeaderSearch &clangHeaderSearchInfo,
411411 const llvm::StringMap<StringRef> &exposedModuleHeaderNames,
412- bool useCxxImport = false ) {
412+ bool useCxxImport = false ,
413+ bool useNonModularIncludes = false ) {
414+ useNonModularIncludes |= frontendOpts.EmitClangHeaderWithNonModularIncludes ;
415+
413416 // Note: we can't use has_feature(modules) as it's always enabled in C++20
414417 // mode.
415418 out << " #if __has_feature(objc_modules)\n " ;
@@ -446,7 +449,7 @@ writeImports(raw_ostream &out, llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
446449 llvm::vfs::FileSystem &fileSystem = fileManager.getVirtualFileSystem ();
447450 llvm::ErrorOr<std::string> cwd = fileSystem.getCurrentWorkingDirectory ();
448451
449- if (frontendOpts. EmitClangHeaderWithNonModularIncludes ) {
452+ if (useNonModularIncludes ) {
450453 assert (cwd && " Access to current working directory required" );
451454
452455 for (auto searchDir = clangHeaderSearchInfo.search_dir_begin ();
@@ -498,7 +501,7 @@ writeImports(raw_ostream &out, llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
498501 }
499502 if (seenImports.insert (Name).second ) {
500503 out << importDirective << ' ' << Name.str () << importDirectiveLineEnd;
501- if (frontendOpts. EmitClangHeaderWithNonModularIncludes ) {
504+ if (useNonModularIncludes ) {
502505 if (const clang::Module *underlyingClangModule =
503506 swiftModule->findUnderlyingClangModule ()) {
504507 collectClangModuleHeaderIncludes (
@@ -521,19 +524,21 @@ writeImports(raw_ostream &out, llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
521524 out << importDirective << ' ' ;
522525 ModuleDecl::ReverseFullNameIterator (clangModule).printForward (out);
523526 out << importDirectiveLineEnd;
524- if (frontendOpts. EmitClangHeaderWithNonModularIncludes ) {
527+ if (useNonModularIncludes ) {
525528 collectClangModuleHeaderIncludes (
526529 clangModule, fileManager, requiredTextualIncludes, visitedModules,
527530 includeDirs, cwd.get ());
528531 }
529532 }
530533 }
531534
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)
535538 out << " #import <" << header << " >\n " ;
536- }
539+ out << " #else\n " ;
540+ for (auto header : requiredTextualIncludes)
541+ out << " #include <" << header << " >\n " ;
537542 }
538543 out << " #endif\n\n " ;
539544 for (const auto header : textualIncludes) {
@@ -544,8 +549,13 @@ writeImports(raw_ostream &out, llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
544549 if (bridgingHeader.empty ())
545550 out << " #import <" << M.getName ().str () << ' /' << M.getName ().str ()
546551 << " .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+ }
549559 }
550560}
551561
@@ -606,17 +616,24 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
606616 writePrologue (os, M->getASTContext (), computeMacroGuard (M));
607617
608618 // C content (@cdecl)
619+ std::string moduleContentsScratch;
609620 if (M->getASTContext ().LangOpts .hasFeature (Feature::CDecl)) {
610621 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 ();
614632 }
615633
616634 // Objective-C content
617635 SmallPtrSet<ImportModuleTy, 8 > imports;
618- std::string objcModuleContentsBuf;
619- llvm::raw_string_ostream objcModuleContents{objcModuleContentsBuf};
636+ llvm::raw_string_ostream objcModuleContents{moduleContentsScratch};
620637 printModuleContentsAsObjC (objcModuleContents, imports, *M, interopContext);
621638 emitObjCConditional (os, [&] {
622639 llvm::StringMap<StringRef> exposedModuleHeaderNames;
0 commit comments