|
| 1 | +//===--- ModuleDependencyScanner.h - Import Swift modules --------*- C++ |
| 2 | +//-*-===// |
| 3 | +// |
| 4 | +// This source file is part of the Swift.org open source project |
| 5 | +// |
| 6 | +// Copyright (c) 2020 Apple Inc. and the Swift project authors |
| 7 | +// Licensed under Apache License v2.0 with Runtime Library Exception |
| 8 | +// |
| 9 | +// See https://swift.org/LICENSE.txt for license information |
| 10 | +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| 11 | +// |
| 12 | +//===----------------------------------------------------------------------===// |
| 13 | + |
| 14 | +#include "swift/AST/ASTContext.h" |
| 15 | +#include "swift/AST/ModuleDependencies.h" |
| 16 | +#include "swift/Frontend/ModuleInterfaceLoader.h" |
| 17 | +#include "swift/Serialization/SerializedModuleLoader.h" |
| 18 | +#include "llvm/Support/ThreadPool.h" |
| 19 | + |
| 20 | +namespace swift { |
| 21 | +class DependencyTracker; |
| 22 | +} |
| 23 | + |
| 24 | +namespace swift { |
| 25 | + |
| 26 | +/// A dependency scanning worker which performs filesystem lookup |
| 27 | +/// of a named module dependency. |
| 28 | +class ModuleDependencyScanningWorker { |
| 29 | +public: |
| 30 | + ModuleDependencyScanningWorker( |
| 31 | + SwiftDependencyScanningService &globalScanningService, |
| 32 | + const CompilerInvocation &ScanCompilerInvocation, |
| 33 | + const SILOptions &SILOptions, ASTContext &ScanASTContext, |
| 34 | + DependencyTracker &DependencyTracker, DiagnosticEngine &diags); |
| 35 | + |
| 36 | +private: |
| 37 | + /// Retrieve the module dependencies for the module with the given name. |
| 38 | + ModuleDependencyVector |
| 39 | + scanFilesystemForModuleDependency(StringRef moduleName, |
| 40 | + const ModuleDependenciesCache &cache, |
| 41 | + bool isTestableImport = false); |
| 42 | + |
| 43 | + /// Retrieve the module dependencies for the Clang module with the given name. |
| 44 | + ModuleDependencyVector |
| 45 | + scanFilesystemForClangModuleDependency(StringRef moduleName, |
| 46 | + const ModuleDependenciesCache &cache); |
| 47 | + |
| 48 | + /// Retrieve the module dependencies for the Swift module with the given name. |
| 49 | + ModuleDependencyVector |
| 50 | + scanFilesystemForSwiftModuleDependency(StringRef moduleName, |
| 51 | + const ModuleDependenciesCache &cache); |
| 52 | + |
| 53 | + // An AST delegate for interface scanning. |
| 54 | + std::unique_ptr<InterfaceSubContextDelegateImpl> ScanningASTDelegate; |
| 55 | + // The Clang scanner tool used by this worker. |
| 56 | + clang::tooling::dependencies::DependencyScanningTool clangScanningTool; |
| 57 | + // Swift and Clang module loaders acting as scanners. |
| 58 | + std::unique_ptr<ModuleInterfaceLoader> swiftScannerModuleLoader; |
| 59 | + std::unique_ptr<ClangImporter> clangScannerModuleLoader; |
| 60 | + // Restrict access to the parent scanner class. |
| 61 | + friend class ModuleDependencyScanner; |
| 62 | +}; |
| 63 | + |
| 64 | +class ModuleDependencyScanner { |
| 65 | +public: |
| 66 | + ModuleDependencyScanner(SwiftDependencyScanningService &ScanningService, |
| 67 | + const CompilerInvocation &ScanCompilerInvocation, |
| 68 | + const SILOptions &SILOptions, |
| 69 | + ASTContext &ScanASTContext, |
| 70 | + DependencyTracker &DependencyTracker, |
| 71 | + DiagnosticEngine &diags, bool ParallelScan); |
| 72 | + |
| 73 | + /// Identify the scanner invocation's main module's dependencies |
| 74 | + llvm::ErrorOr<ModuleDependencyInfo> getMainModuleDependencyInfo( |
| 75 | + ModuleDecl *mainModule, |
| 76 | + llvm::Optional<SwiftDependencyTracker> tracker = llvm::None); |
| 77 | + |
| 78 | + /// Resolve module dependencies of the given module, computing a full |
| 79 | + /// transitive closure dependency graph. |
| 80 | + std::vector<ModuleDependencyID> |
| 81 | + getModuleDependencies(ModuleDependencyID moduleID, |
| 82 | + ModuleDependenciesCache &cache); |
| 83 | + |
| 84 | + /// Query the module dependency info for the Clang module with the given name. |
| 85 | + /// Explicit by-name lookups are useful for batch mode scanning. |
| 86 | + llvm::Optional<const ModuleDependencyInfo *> |
| 87 | + getNamedClangModuleDependencyInfo(StringRef moduleName, |
| 88 | + ModuleDependenciesCache &cache); |
| 89 | + |
| 90 | + /// Query the module dependency info for the Swift module with the given name. |
| 91 | + /// Explicit by-name lookups are useful for batch mode scanning. |
| 92 | + llvm::Optional<const ModuleDependencyInfo *> |
| 93 | + getNamedSwiftModuleDependencyInfo(StringRef moduleName, |
| 94 | + ModuleDependenciesCache &cache); |
| 95 | + |
| 96 | +private: |
| 97 | + /// Resolve the direct dependencies of the given module. |
| 98 | + std::vector<ModuleDependencyID> |
| 99 | + resolveDirectModuleDependencies(ModuleDependencyID moduleID, |
| 100 | + ModuleDependenciesCache &cache); |
| 101 | + |
| 102 | + /// Resolve imported module names of a given module to concrete |
| 103 | + /// modules. If `ParallelScan` is enabled, this operation is multithreaded. |
| 104 | + void |
| 105 | + resolveImportDependencies(const ModuleDependencyID &moduleID, |
| 106 | + ModuleDependenciesCache &cache, |
| 107 | + ModuleDependencyIDSetVector &directDependencies); |
| 108 | + |
| 109 | + /// If a module has a bridging header, execute a dependency scan |
| 110 | + /// on it and record the dependencies. |
| 111 | + void resolveBridgingHeaderDependencies( |
| 112 | + const ModuleDependencyID &moduleID, ModuleDependenciesCache &cache, |
| 113 | + std::vector<std::string> &allClangModules, |
| 114 | + llvm::StringSet<> &alreadyKnownModules, |
| 115 | + ModuleDependencyIDSetVector &directDependencies); |
| 116 | + |
| 117 | + /// Resolve all module dependencies comprised of Swift overlays |
| 118 | + /// of this module's Clang module dependencies. |
| 119 | + void resolveSwiftOverlayDependencies( |
| 120 | + const ModuleDependencyID &moduleID, |
| 121 | + const std::vector<std::string> &clangDependencies, |
| 122 | + ModuleDependenciesCache &cache, |
| 123 | + ModuleDependencyIDSetVector &swiftOverlayDependencies); |
| 124 | + |
| 125 | + /// Identify all cross-import overlay modules of the specified |
| 126 | + /// dependency set and apply an action for each. |
| 127 | + void discoverCrossImportOverlayDependencies( |
| 128 | + StringRef mainModuleName, ArrayRef<ModuleDependencyID> allDependencies, |
| 129 | + ModuleDependenciesCache &cache, |
| 130 | + llvm::function_ref<void(ModuleDependencyID)> action); |
| 131 | + |
| 132 | + /// Perform an operation utilizing one of the Scanning workers |
| 133 | + /// available to this scanner. |
| 134 | + template <typename Function, typename... Args> |
| 135 | + auto withDependencyScanningWorker(Function &&F, Args &&...ArgList); |
| 136 | + |
| 137 | +private: |
| 138 | + const CompilerInvocation &ScanCompilerInvocation; |
| 139 | + ASTContext &ScanASTContext; |
| 140 | + DiagnosticEngine &Diagnostics; |
| 141 | + |
| 142 | + /// The available pool of workers for filesystem module search |
| 143 | + unsigned NumThreads; |
| 144 | + std::list<std::unique_ptr<ModuleDependencyScanningWorker>> Workers; |
| 145 | + llvm::ThreadPool ScanningThreadPool; |
| 146 | + /// Protect worker access. |
| 147 | + std::mutex WorkersLock; |
| 148 | +}; |
| 149 | + |
| 150 | +} // namespace swift |
0 commit comments