2323#include " swift/ClangImporter/ClangImporter.h"
2424#include " swift/Frontend/FrontendOptions.h"
2525
26- #include " clang/Basic/FileManager.h"
2726#include " clang/Basic/Module.h"
28- #include " clang/Lex/HeaderSearch.h"
2927
30- #include " llvm/Support/FormatVariadic.h"
31- #include " llvm/Support/Path.h"
3228#include " llvm/Support/raw_ostream.h"
3329
3430using namespace swift ;
@@ -390,133 +386,9 @@ static int compareImportModulesByName(const ImportModuleTy *left,
390386 return 1 ;
391387}
392388
393- // Makes the provided path absolute and removes any "." or ".." segments from
394- // the path
395- static llvm::SmallString<128 > normalizePath (const llvm::StringRef path) {
396- llvm::SmallString<128 > result = path;
397- llvm::sys::path::remove_dots (result, /* remove_dot_dot */ true );
398- llvm::sys::fs::make_absolute (result);
399- return result;
400- }
401-
402- // Collect the set of header includes needed to import the given Clang module
403- // into an ObjectiveC program. Modeled after collectModuleHeaderIncludes in the
404- // Clang frontend (FrontendAction.cpp)
405- // Augment requiredTextualIncludes with the set of headers required.
406- static void collectClangModuleHeaderIncludes (
407- const clang::Module *clangModule, clang::FileManager &fileManager,
408- llvm::SmallSet<llvm::SmallString<128 >, 10 > &requiredTextualIncludes,
409- llvm::SmallSet<const clang::Module *, 10 > &visitedModules,
410- const llvm::SmallSet<llvm::SmallString<128 >, 10 > &includeDirs,
411- const llvm::StringRef cwd) {
412-
413- if (!visitedModules.insert (clangModule).second )
414- return ;
415-
416- auto addHeader = [&](llvm::StringRef headerPath,
417- llvm::StringRef pathRelativeToRootModuleDir) {
418- if (!clangModule->Directory )
419- return ;
420-
421- llvm::SmallString<128 > textualInclude = normalizePath (headerPath);
422- llvm::SmallString<128 > containingSearchDirPath;
423-
424- for (auto &includeDir : includeDirs) {
425- if (textualInclude.startswith (includeDir)) {
426- if (includeDir.size () > containingSearchDirPath.size ()) {
427- containingSearchDirPath = includeDir;
428- }
429- }
430- }
431-
432- if (!containingSearchDirPath.empty ()) {
433- llvm::SmallString<128 > prefixToRemove =
434- llvm::formatv (" {0}/" , containingSearchDirPath);
435- llvm::sys::path::replace_path_prefix (textualInclude, prefixToRemove, " " );
436- } else {
437- // If we cannot find find the module map on the search path,
438- // fallback to including the header using the provided path relative
439- // to the module map
440- textualInclude = pathRelativeToRootModuleDir;
441- }
442-
443- if (clangModule->getTopLevelModule ()->IsFramework ) {
444- llvm::SmallString<32 > frameworkName =
445- clangModule->getTopLevelModuleName ();
446- llvm::SmallString<64 > oldFrameworkPrefix =
447- llvm::formatv (" {0}.framework/Headers" , frameworkName);
448- llvm::sys::path::replace_path_prefix (textualInclude, oldFrameworkPrefix,
449- frameworkName);
450- }
451-
452- requiredTextualIncludes.insert (textualInclude);
453- };
454-
455- if (clang::Module::Header umbrellaHeader = clangModule->getUmbrellaHeader ()) {
456- addHeader (umbrellaHeader.Entry ->tryGetRealPathName (),
457- umbrellaHeader.PathRelativeToRootModuleDirectory );
458- } else if (clang::Module::DirectoryName umbrellaDir =
459- clangModule->getUmbrellaDir ()) {
460- SmallString<128 > nativeUmbrellaDirPath;
461- std::error_code errorCode;
462- llvm::sys::path::native (umbrellaDir.Entry ->getName (),
463- nativeUmbrellaDirPath);
464- llvm::vfs::FileSystem &fileSystem = fileManager.getVirtualFileSystem ();
465- for (llvm::vfs::recursive_directory_iterator
466- dir (fileSystem, nativeUmbrellaDirPath, errorCode),
467- end;
468- dir != end && !errorCode; dir.increment (errorCode)) {
469-
470- if (llvm::StringSwitch<bool >(llvm::sys::path::extension (dir->path ()))
471- .Cases (" .h" , " .H" , " .hh" , " .hpp" , true )
472- .Default (false )) {
473-
474- // Compute path to the header relative to the root of the module
475- // (location of the module map) First compute the relative path from
476- // umbrella directory to header file
477- SmallVector<StringRef> pathComponents;
478- auto pathIt = llvm::sys::path::rbegin (dir->path ());
479-
480- for (int i = 0 ; i != dir.level () + 1 ; ++i, ++pathIt)
481- pathComponents.push_back (*pathIt);
482- // Then append this to the path from module root to umbrella dir
483- SmallString<128 > relativeHeaderPath;
484- if (umbrellaDir.PathRelativeToRootModuleDirectory != " ." )
485- relativeHeaderPath += umbrellaDir.PathRelativeToRootModuleDirectory ;
486-
487- for (auto it = pathComponents.rbegin (), end = pathComponents.rend ();
488- it != end; ++it) {
489- llvm::sys::path::append (relativeHeaderPath, *it);
490- }
491-
492- addHeader (dir->path (), relativeHeaderPath);
493- }
494- }
495- } else {
496- for (clang::Module::HeaderKind headerKind :
497- {clang::Module::HK_Normal, clang::Module::HK_Textual}) {
498- for (const clang::Module::Header &header :
499- clangModule->Headers [headerKind]) {
500- addHeader (header.Entry ->tryGetRealPathName (),
501- header.PathRelativeToRootModuleDirectory );
502- }
503- }
504- for (auto submodule : clangModule->submodules ()) {
505- if (submodule->IsExplicit )
506- continue ;
507-
508- collectClangModuleHeaderIncludes (submodule, fileManager,
509- requiredTextualIncludes, visitedModules,
510- includeDirs, cwd);
511- }
512- }
513- }
514-
515389static void writeImports (raw_ostream &out,
516390 llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
517391 ModuleDecl &M, StringRef bridgingHeader,
518- const FrontendOptions &frontendOpts,
519- clang::HeaderSearch &clangHeaderSearchInfo,
520392 bool useCxxImport = false ) {
521393 // Note: we can't use has_feature(modules) as it's always enabled in C++20
522394 // mode.
@@ -541,45 +413,6 @@ static void writeImports(raw_ostream &out,
541413 return import == importer->getImportedHeaderModule ();
542414 };
543415
544- clang::FileSystemOptions fileSystemOptions;
545- clang::FileManager fileManager{fileSystemOptions};
546-
547- llvm::SmallSet<llvm::SmallString<128 >, 10 > requiredTextualIncludes;
548- llvm::SmallSet<const clang::Module *, 10 > visitedModules;
549- llvm::SmallSet<llvm::SmallString<128 >, 10 > includeDirs;
550-
551- llvm::vfs::FileSystem &fileSystem = fileManager.getVirtualFileSystem ();
552- llvm::ErrorOr<std::string> cwd = fileSystem.getCurrentWorkingDirectory ();
553-
554- if (frontendOpts.EmitClangHeaderWithNonModularIncludes ) {
555- assert (cwd && " Access to current working directory required" );
556-
557- for (auto searchDir = clangHeaderSearchInfo.search_dir_begin ();
558- searchDir != clangHeaderSearchInfo.search_dir_end (); ++searchDir) {
559- includeDirs.insert (normalizePath (searchDir->getName ()));
560- }
561-
562- const clang::Module *foundationModule = clangHeaderSearchInfo.lookupModule (
563- " Foundation" , clang::SourceLocation (), false , false );
564- const clang::Module *darwinModule = clangHeaderSearchInfo.lookupModule (
565- " Darwin" , clang::SourceLocation (), false , false );
566-
567- std::function<void (const clang::Module *)>
568- collectTransitiveSubmoduleClosure;
569- collectTransitiveSubmoduleClosure = [&](const clang::Module *module ) {
570- if (!module )
571- return ;
572-
573- visitedModules.insert (module );
574- for (auto submodule : module ->submodules ()) {
575- collectTransitiveSubmoduleClosure (submodule);
576- }
577- };
578-
579- collectTransitiveSubmoduleClosure (foundationModule);
580- collectTransitiveSubmoduleClosure (darwinModule);
581- }
582-
583416 // Track printed names to handle overlay modules.
584417 llvm::SmallPtrSet<Identifier, 8 > seenImports;
585418 bool includeUnderlying = false ;
@@ -592,46 +425,18 @@ static void writeImports(raw_ostream &out,
592425 includeUnderlying = true ;
593426 continue ;
594427 }
595- if (seenImports.insert (Name).second ) {
428+ if (seenImports.insert (Name).second )
596429 out << importDirective << ' ' << Name.str () << " ;\n " ;
597- if (frontendOpts.EmitClangHeaderWithNonModularIncludes ) {
598- if (const clang::Module *underlyingClangModule =
599- swiftModule->findUnderlyingClangModule ()) {
600- collectClangModuleHeaderIncludes (
601- underlyingClangModule, fileManager, requiredTextualIncludes,
602- visitedModules, includeDirs, cwd.get ());
603- } else if ((underlyingClangModule =
604- clangHeaderSearchInfo.lookupModule (
605- Name.str (), clang::SourceLocation (), true ,
606- true ))) {
607- collectClangModuleHeaderIncludes (
608- underlyingClangModule, fileManager, requiredTextualIncludes,
609- visitedModules, includeDirs, cwd.get ());
610- }
611- }
612- }
613430 } else {
614431 const auto *clangModule = import .get <const clang::Module *>();
615432 assert (clangModule->isSubModule () &&
616433 " top-level modules should use a normal swift::ModuleDecl" );
617434 out << importDirective << ' ' ;
618435 ModuleDecl::ReverseFullNameIterator (clangModule).printForward (out);
619436 out << " ;\n " ;
620-
621- if (frontendOpts.EmitClangHeaderWithNonModularIncludes ) {
622- collectClangModuleHeaderIncludes (
623- clangModule, fileManager, requiredTextualIncludes, visitedModules,
624- includeDirs, cwd.get ());
625- }
626437 }
627438 }
628439
629- if (frontendOpts.EmitClangHeaderWithNonModularIncludes ) {
630- out << " #else\n " ;
631- for (auto header : requiredTextualIncludes) {
632- out << " #import <" << header << " >\n " ;
633- }
634- }
635440 out << " #endif\n\n " ;
636441
637442 if (includeUnderlying) {
@@ -685,8 +490,7 @@ static std::string computeMacroGuard(const ModuleDecl *M) {
685490bool swift::printAsClangHeader (raw_ostream &os, ModuleDecl *M,
686491 StringRef bridgingHeader,
687492 const FrontendOptions &frontendOpts,
688- const IRGenOptions &irGenOpts,
689- clang::HeaderSearch &clangHeaderSearchInfo) {
493+ const IRGenOptions &irGenOpts) {
690494 llvm::PrettyStackTraceString trace (" While generating Clang header" );
691495
692496 SwiftToClangInteropContext interopContext (*M, irGenOpts);
@@ -696,10 +500,8 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
696500 llvm::raw_string_ostream objcModuleContents{objcModuleContentsBuf};
697501 printModuleContentsAsObjC (objcModuleContents, imports, *M, interopContext);
698502 writePrologue (os, M->getASTContext (), computeMacroGuard (M));
699- emitObjCConditional (os, [&] {
700- writeImports (os, imports, *M, bridgingHeader, frontendOpts,
701- clangHeaderSearchInfo);
702- });
503+ emitObjCConditional (os,
504+ [&] { writeImports (os, imports, *M, bridgingHeader); });
703505 writePostImportPrologue (os, *M);
704506 emitObjCConditional (os, [&] { os << objcModuleContents.str (); });
705507 emitCxxConditional (os, [&] {
@@ -728,8 +530,8 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
728530 moduleContents, *M, interopContext,
729531 /* requiresExposedAttribute=*/ requiresExplicitExpose);
730532 // FIXME: In ObjC++ mode, we do not need to reimport duplicate modules.
731- writeImports (os, deps.imports , *M, bridgingHeader, frontendOpts,
732- clangHeaderSearchInfo, /* useCxxImport= */ true );
533+ writeImports (os, deps.imports , *M, bridgingHeader, /* useCxxImport= */ true );
534+
733535 // Embed the standard library directly.
734536 if (defaultDependencyBehavior && deps.dependsOnStandardLibrary ) {
735537 assert (!M->isStdlibModule ());
0 commit comments