23
23
#include " swift/ClangImporter/ClangImporter.h"
24
24
#include " swift/Frontend/FrontendOptions.h"
25
25
26
- #include " clang/Basic/FileManager.h"
27
26
#include " clang/Basic/Module.h"
28
- #include " clang/Lex/HeaderSearch.h"
29
27
30
- #include " llvm/Support/FormatVariadic.h"
31
- #include " llvm/Support/Path.h"
32
28
#include " llvm/Support/raw_ostream.h"
33
29
34
30
using namespace swift ;
@@ -390,133 +386,9 @@ static int compareImportModulesByName(const ImportModuleTy *left,
390
386
return 1 ;
391
387
}
392
388
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
-
515
389
static void writeImports (raw_ostream &out,
516
390
llvm::SmallPtrSetImpl<ImportModuleTy> &imports,
517
391
ModuleDecl &M, StringRef bridgingHeader,
518
- const FrontendOptions &frontendOpts,
519
- clang::HeaderSearch &clangHeaderSearchInfo,
520
392
bool useCxxImport = false ) {
521
393
// Note: we can't use has_feature(modules) as it's always enabled in C++20
522
394
// mode.
@@ -541,45 +413,6 @@ static void writeImports(raw_ostream &out,
541
413
return import == importer->getImportedHeaderModule ();
542
414
};
543
415
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
-
583
416
// Track printed names to handle overlay modules.
584
417
llvm::SmallPtrSet<Identifier, 8 > seenImports;
585
418
bool includeUnderlying = false ;
@@ -592,46 +425,18 @@ static void writeImports(raw_ostream &out,
592
425
includeUnderlying = true ;
593
426
continue ;
594
427
}
595
- if (seenImports.insert (Name).second ) {
428
+ if (seenImports.insert (Name).second )
596
429
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
- }
613
430
} else {
614
431
const auto *clangModule = import .get <const clang::Module *>();
615
432
assert (clangModule->isSubModule () &&
616
433
" top-level modules should use a normal swift::ModuleDecl" );
617
434
out << importDirective << ' ' ;
618
435
ModuleDecl::ReverseFullNameIterator (clangModule).printForward (out);
619
436
out << " ;\n " ;
620
-
621
- if (frontendOpts.EmitClangHeaderWithNonModularIncludes ) {
622
- collectClangModuleHeaderIncludes (
623
- clangModule, fileManager, requiredTextualIncludes, visitedModules,
624
- includeDirs, cwd.get ());
625
- }
626
437
}
627
438
}
628
439
629
- if (frontendOpts.EmitClangHeaderWithNonModularIncludes ) {
630
- out << " #else\n " ;
631
- for (auto header : requiredTextualIncludes) {
632
- out << " #import <" << header << " >\n " ;
633
- }
634
- }
635
440
out << " #endif\n\n " ;
636
441
637
442
if (includeUnderlying) {
@@ -685,8 +490,7 @@ static std::string computeMacroGuard(const ModuleDecl *M) {
685
490
bool swift::printAsClangHeader (raw_ostream &os, ModuleDecl *M,
686
491
StringRef bridgingHeader,
687
492
const FrontendOptions &frontendOpts,
688
- const IRGenOptions &irGenOpts,
689
- clang::HeaderSearch &clangHeaderSearchInfo) {
493
+ const IRGenOptions &irGenOpts) {
690
494
llvm::PrettyStackTraceString trace (" While generating Clang header" );
691
495
692
496
SwiftToClangInteropContext interopContext (*M, irGenOpts);
@@ -696,10 +500,8 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
696
500
llvm::raw_string_ostream objcModuleContents{objcModuleContentsBuf};
697
501
printModuleContentsAsObjC (objcModuleContents, imports, *M, interopContext);
698
502
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); });
703
505
writePostImportPrologue (os, *M);
704
506
emitObjCConditional (os, [&] { os << objcModuleContents.str (); });
705
507
emitCxxConditional (os, [&] {
@@ -728,8 +530,8 @@ bool swift::printAsClangHeader(raw_ostream &os, ModuleDecl *M,
728
530
moduleContents, *M, interopContext,
729
531
/* requiresExposedAttribute=*/ requiresExplicitExpose);
730
532
// 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
+
733
535
// Embed the standard library directly.
734
536
if (defaultDependencyBehavior && deps.dependsOnStandardLibrary ) {
735
537
assert (!M->isStdlibModule ());
0 commit comments