@@ -451,86 +451,96 @@ ClangImporter::getModuleDependencies(Identifier moduleName,
451
451
});
452
452
}
453
453
454
- bool ClangImporter::addBridgingHeaderDependencies (
454
+ bool ClangImporter::addHeaderDependencies (
455
455
ModuleDependencyID moduleID,
456
456
clang::tooling::dependencies::DependencyScanningTool &clangScanningTool,
457
457
ModuleDependenciesCache &cache) {
458
458
auto &ctx = Impl.SwiftContext ;
459
459
auto optionalTargetModule = cache.findDependency (moduleID);
460
460
assert (optionalTargetModule.has_value ());
461
461
auto targetModule = *(optionalTargetModule.value ());
462
-
463
462
// If we've already recorded bridging header dependencies, we're done.
464
- if (auto swiftInterfaceDeps = targetModule.getAsSwiftInterfaceModule ()) {
465
- if (!swiftInterfaceDeps->textualModuleDetails .bridgingSourceFiles .empty () ||
466
- !swiftInterfaceDeps->textualModuleDetails .bridgingModuleDependencies
467
- .empty ())
468
- return false ;
469
- } else if (auto swiftSourceDeps = targetModule.getAsSwiftSourceModule ()) {
470
- if (!swiftSourceDeps->textualModuleDetails .bridgingSourceFiles .empty () ||
471
- !swiftSourceDeps->textualModuleDetails .bridgingModuleDependencies
472
- .empty ())
473
- return false ;
474
- } else {
475
- llvm_unreachable (" Unexpected module dependency kind" );
476
- }
463
+ if (!targetModule.getHeaderDependencies ().empty () ||
464
+ !targetModule.getHeaderInputSourceFiles ().empty ())
465
+ return false ;
466
+
467
+ // Scan the specified textual header file and record its dependencies
468
+ // into the cache
469
+ auto scanHeaderDependencies =
470
+ [&](StringRef headerPath) -> llvm::Expected<TranslationUnitDeps> {
471
+ auto &ctx = Impl.SwiftContext ;
472
+ std::vector<std::string> commandLineArgs =
473
+ getClangDepScanningInvocationArguments (ctx, StringRef (headerPath));
474
+ auto optionalWorkingDir =
475
+ computeClangWorkingDirectory (commandLineArgs, ctx);
476
+ if (!optionalWorkingDir) {
477
+ ctx.Diags .diagnose (SourceLoc (), diag::clang_dependency_scan_error,
478
+ " Missing '-working-directory' argument" );
479
+ return llvm::errorCodeToError (
480
+ std::error_code (errno, std::generic_category ()));
481
+ }
482
+ std::string workingDir = *optionalWorkingDir;
483
+ auto moduleCachePath = getModuleCachePathFromClang (getClangInstance ());
484
+ auto lookupModuleOutput =
485
+ [moduleCachePath](const ModuleID &MID,
486
+ ModuleOutputKind MOK) -> std::string {
487
+ return moduleCacheRelativeLookupModuleOutput (MID, MOK, moduleCachePath);
488
+ };
489
+ auto dependencies = clangScanningTool.getTranslationUnitDependencies (
490
+ commandLineArgs, workingDir, cache.getAlreadySeenClangModules (),
491
+ lookupModuleOutput);
492
+ if (!dependencies) {
493
+ // FIXME: Route this to a normal diagnostic.
494
+ llvm::logAllUnhandledErrors (dependencies.takeError (), llvm::errs ());
495
+ return dependencies.takeError ();
496
+ }
477
497
478
- // Retrieve the bridging header.
479
- std::string bridgingHeader = *(targetModule.getBridgingHeader ());
498
+ // Record module dependencies for each new module we found.
499
+ auto bridgedDeps = bridgeClangModuleDependencies (
500
+ clangScanningTool, dependencies->ModuleGraph ,
501
+ cache.getModuleOutputPath (),
502
+ [&cache](StringRef path) {
503
+ return cache.getScanService ().remapPath (path);
504
+ });
505
+ cache.recordDependencies (bridgedDeps);
480
506
481
- // Determine the command-line arguments for dependency scanning.
482
- std::vector<std::string> commandLineArgs =
483
- getClangDepScanningInvocationArguments (ctx, StringRef (bridgingHeader));
484
- auto optionalWorkingDir = computeClangWorkingDirectory (commandLineArgs, ctx);
485
- if (!optionalWorkingDir) {
486
- ctx.Diags .diagnose (SourceLoc (), diag::clang_dependency_scan_error,
487
- " Missing '-working-directory' argument" );
488
- return true ;
489
- }
490
- std::string workingDir = *optionalWorkingDir;
507
+ // Record dependencies for the source files the bridging header includes.
508
+ for (const auto &fileDep : dependencies->FileDeps )
509
+ targetModule.addHeaderSourceFile (fileDep);
491
510
492
- auto moduleCachePath = getModuleCachePathFromClang (getClangInstance ());
493
- auto lookupModuleOutput =
494
- [moduleCachePath](const ModuleID &MID,
495
- ModuleOutputKind MOK) -> std::string {
496
- return moduleCacheRelativeLookupModuleOutput (MID, MOK, moduleCachePath);
511
+ // ... and all module dependencies.
512
+ llvm::StringSet<> alreadyAddedModules;
513
+ for (const auto &moduleDep : dependencies->ClangModuleDeps )
514
+ targetModule.addHeaderInputModuleDependency (moduleDep.ModuleName ,
515
+ alreadyAddedModules);
516
+
517
+ return dependencies;
497
518
};
498
519
499
- auto clangModuleDependencies =
500
- clangScanningTool.getTranslationUnitDependencies (
501
- commandLineArgs, workingDir, cache.getAlreadySeenClangModules (),
502
- lookupModuleOutput);
503
- if (!clangModuleDependencies) {
504
- // FIXME: Route this to a normal diagnostic.
505
- llvm::logAllUnhandledErrors (clangModuleDependencies.takeError (), llvm::errs ());
506
- return true ;
520
+ // - Textual module dependencies require us to process their bridging header.
521
+ // - Binary module dependnecies may have arbitrary header inputs.
522
+ if (targetModule.isTextualSwiftModule () &&
523
+ !targetModule.getBridgingHeader ()->empty ()) {
524
+ auto clangModuleDependencies =
525
+ scanHeaderDependencies (*targetModule.getBridgingHeader ());
526
+ if (!clangModuleDependencies)
527
+ return true ;
528
+ if (auto TreeID = clangModuleDependencies->IncludeTreeID )
529
+ targetModule.addBridgingHeaderIncludeTree (*TreeID);
530
+ recordBridgingHeaderOptions (targetModule, *clangModuleDependencies);
531
+ // Update the cache with the new information for the module.
532
+ cache.updateDependency (moduleID, targetModule);
533
+ } else if (targetModule.isSwiftBinaryModule ()) {
534
+ auto swiftBinaryDeps = targetModule.getAsSwiftBinaryModule ();
535
+ if (!swiftBinaryDeps->headerImports .empty ()) {
536
+ auto clangModuleDependencies = scanHeaderDependencies (swiftBinaryDeps->headerImports .front ());
537
+ if (!clangModuleDependencies)
538
+ return true ;
539
+ // TODO: CAS will require a header include tree for this.
540
+ // Update the cache with the new information for the module.
541
+ cache.updateDependency (moduleID, targetModule);
542
+ }
507
543
}
508
544
509
- // Record module dependencies for each new module we found.
510
- auto bridgedDeps = bridgeClangModuleDependencies (
511
- clangScanningTool, clangModuleDependencies->ModuleGraph ,
512
- cache.getModuleOutputPath (), [&cache](StringRef path) {
513
- return cache.getScanService ().remapPath (path);
514
- });
515
- cache.recordDependencies (bridgedDeps);
516
-
517
- // Record dependencies for the source files the bridging header includes.
518
- for (const auto &fileDep : clangModuleDependencies->FileDeps )
519
- targetModule.addBridgingSourceFile (fileDep);
520
-
521
- // ... and all module dependencies.
522
- llvm::StringSet<> alreadyAddedModules;
523
- for (const auto &moduleDep : clangModuleDependencies->ClangModuleDeps )
524
- targetModule.addBridgingModuleDependency (moduleDep.ModuleName ,
525
- alreadyAddedModules);
526
-
527
- if (auto TreeID = clangModuleDependencies->IncludeTreeID )
528
- targetModule.addBridgingHeaderIncludeTree (*TreeID);
529
-
530
- recordBridgingHeaderOptions (targetModule, *clangModuleDependencies);
531
-
532
- // Update the cache with the new information for the module.
533
- cache.updateDependency (moduleID, targetModule);
534
-
535
545
return false ;
536
546
}
0 commit comments