Files
swift-mirror/include/swift/AST/ModuleDependencies.h

728 lines
29 KiB
C++

//===--- ModuleDependencies.h - Module Dependencies -------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines data structures for capturing all of the source files
// and modules on which a given module depends, forming a graph of all of the
// modules that need to be present for a given module to be built.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_AST_MODULE_DEPENDENCIES_H
#define SWIFT_AST_MODULE_DEPENDENCIES_H
#include "swift/Basic/LLVM.h"
#include "swift/AST/Import.h"
#include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringSet.h"
#include <string>
#include <vector>
#include <unordered_map>
namespace swift {
class ClangModuleDependenciesCacheImpl;
class SourceFile;
class ASTContext;
class Identifier;
class CompilerInstance;
/// Which kind of module dependencies we are looking for.
enum class ModuleDependencyKind : int8_t {
FirstKind,
// Textual Swift dependency
SwiftInterface = FirstKind,
// Binary module Swift dependency
SwiftBinary,
// Clang module dependency
Clang,
// Used to model the translation unit's source module
SwiftSource,
// Placeholder dependencies are a kind of dependencies used only by the
// dependency scanner. They are swift modules that the scanner will not be
// able to locate in its search paths and which are the responsibility of the
// scanner's client to ensure are provided.
//
// Placeholder dependencies will be specified in the scanner's output
// dependency graph where it is the responsibility of the scanner's client to
// ensure required post-processing takes place to "resolve" them. In order to
// do so, the client (swift driver, or any other client build system) is
// expected to have access to a full dependency graph of all placeholder
// dependencies and be able to replace placeholder nodes in the dependency
// graph with their full dependency trees, `uniquing` common dependency module
// nodes in the process.
//
// One example where placeholder dependencies are employed is when using
// SwiftPM in Explicit Module Build mode. SwiftPM constructs a build plan for
// all targets ahead-of-time. When planning a build for a target that depends
// on other targets, the dependency scanning action is not able to locate
// dependency target modules, because they have not yet been built. Instead,
// the build system treats them as placeholder dependencies and resolves them
// with `actual` dependencies in a post-processing step once dependency graphs
// of all targets, individually, have been computed.
SwiftPlaceholder,
LastKind = SwiftPlaceholder + 1
};
struct ModuleDependencyKindHash {
std::size_t operator()(ModuleDependencyKind k) const {
using UnderlyingType = std::underlying_type<ModuleDependencyKind>::type;
return std::hash<UnderlyingType>{}(static_cast<UnderlyingType>(k));
}
};
/// Base class for the variant storage of ModuleDependencyInfo.
///
/// This class is mostly an implementation detail for \c ModuleDependencyInfo.
class ModuleDependencyInfoStorageBase {
public:
const ModuleDependencyKind dependencyKind;
ModuleDependencyInfoStorageBase(ModuleDependencyKind dependencyKind)
: dependencyKind(dependencyKind) { }
virtual ModuleDependencyInfoStorageBase *clone() const = 0;
virtual ~ModuleDependencyInfoStorageBase();
/// The set of modules on which this module depends.
std::vector<std::string> moduleDependencies;
};
struct CommonSwiftTextualModuleDependencyDetails {
CommonSwiftTextualModuleDependencyDetails(ArrayRef<StringRef> extraPCMArgs)
: extraPCMArgs(extraPCMArgs.begin(), extraPCMArgs.end()) {}
/// To build a PCM to be used by this Swift module, we need to append these
/// arguments to the generic PCM build arguments reported from the dependency
/// graph.
const std::vector<std::string> extraPCMArgs;
/// Bridging header file, if there is one.
Optional<std::string> bridgingHeaderFile;
/// Source files on which the bridging header depends.
std::vector<std::string> bridgingSourceFiles;
/// (Clang) modules on which the bridging header depends.
std::vector<std::string> bridgingModuleDependencies;
};
/// Describes the dependencies of a Swift module described by an Swift interface file.
///
/// This class is mostly an implementation detail for \c ModuleDependencyInfo.
class SwiftInterfaceModuleDependenciesStorage :
public ModuleDependencyInfoStorageBase {
public:
/// Destination output path
const std::string moduleOutputPath;
/// The Swift interface file to be used to generate the module file.
const std::string swiftInterfaceFile;
/// Potentially ready-to-use compiled modules for the interface file.
const std::vector<std::string> compiledModuleCandidates;
/// The Swift frontend invocation arguments to build the Swift module from the
/// interface.
const std::vector<std::string> buildCommandLine;
/// The hash value that will be used for the generated module
const std::string contextHash;
/// A flag that indicates this dependency is a framework
const bool isFramework;
/// Details common to Swift textual (interface or source) modules
CommonSwiftTextualModuleDependencyDetails textualModuleDetails;
SwiftInterfaceModuleDependenciesStorage(
const std::string moduleOutputPath,
const std::string swiftInterfaceFile,
ArrayRef<std::string> compiledModuleCandidates,
ArrayRef<StringRef> buildCommandLine,
ArrayRef<StringRef> extraPCMArgs,
StringRef contextHash,
bool isFramework
) : ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftInterface),
moduleOutputPath(moduleOutputPath),
swiftInterfaceFile(swiftInterfaceFile),
compiledModuleCandidates(compiledModuleCandidates.begin(),
compiledModuleCandidates.end()),
buildCommandLine(buildCommandLine.begin(), buildCommandLine.end()),
contextHash(contextHash), isFramework(isFramework),
textualModuleDetails(extraPCMArgs)
{}
ModuleDependencyInfoStorageBase *clone() const override {
return new SwiftInterfaceModuleDependenciesStorage(*this);
}
static bool classof(const ModuleDependencyInfoStorageBase *base) {
return base->dependencyKind == ModuleDependencyKind::SwiftInterface;
}
};
/// Describes the dependencies of a Swift module
///
/// This class is mostly an implementation detail for \c ModuleDependencyInfo.
class SwiftSourceModuleDependenciesStorage :
public ModuleDependencyInfoStorageBase {
public:
/// Swift source files that are part of the Swift module, when known.
std::vector<std::string> sourceFiles;
/// Details common to Swift textual (interface or source) modules
CommonSwiftTextualModuleDependencyDetails textualModuleDetails;
SwiftSourceModuleDependenciesStorage(
ArrayRef<StringRef> extraPCMArgs
) : ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftSource),
textualModuleDetails(extraPCMArgs) {}
ModuleDependencyInfoStorageBase *clone() const override {
return new SwiftSourceModuleDependenciesStorage(*this);
}
static bool classof(const ModuleDependencyInfoStorageBase *base) {
return base->dependencyKind == ModuleDependencyKind::SwiftSource;
}
};
/// Describes the dependencies of a pre-built Swift module (with no .swiftinterface).
///
/// This class is mostly an implementation detail for \c ModuleDependencyInfo.
class SwiftBinaryModuleDependencyStorage : public ModuleDependencyInfoStorageBase {
public:
SwiftBinaryModuleDependencyStorage(const std::string &compiledModulePath,
const std::string &moduleDocPath,
const std::string &sourceInfoPath,
const bool isFramework)
: ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftBinary),
compiledModulePath(compiledModulePath),
moduleDocPath(moduleDocPath),
sourceInfoPath(sourceInfoPath),
isFramework(isFramework) {}
ModuleDependencyInfoStorageBase *clone() const override {
return new SwiftBinaryModuleDependencyStorage(*this);
}
/// The path to the .swiftmodule file.
const std::string compiledModulePath;
/// The path to the .swiftModuleDoc file.
const std::string moduleDocPath;
/// The path to the .swiftSourceInfo file.
const std::string sourceInfoPath;
/// A flag that indicates this dependency is a framework
const bool isFramework;
static bool classof(const ModuleDependencyInfoStorageBase *base) {
return base->dependencyKind == ModuleDependencyKind::SwiftBinary;
}
};
/// Describes the dependencies of a Clang module.
///
/// This class is mostly an implementation detail for \c ModuleDependencyInfo.
class ClangModuleDependencyStorage : public ModuleDependencyInfoStorageBase {
public:
/// Destination output path
const std::string pcmOutputPath;
/// The module map file used to generate the Clang module.
const std::string moduleMapFile;
/// The context hash describing the configuration options for this module.
const std::string contextHash;
/// Partial (Clang) command line that can be used to build this module.
const std::vector<std::string> nonPathCommandLine;
/// The file dependencies
const std::vector<std::string> fileDependencies;
/// The swift-specific PCM arguments captured by this dependencies object
/// as found by the scanning action that discovered it
const std::vector<std::string> capturedPCMArgs;
ClangModuleDependencyStorage(
const std::string &pcmOutputPath,
const std::string &moduleMapFile,
const std::string &contextHash,
const std::vector<std::string> &nonPathCommandLine,
const std::vector<std::string> &fileDependencies,
const std::vector<std::string> &capturedPCMArgs
) : ModuleDependencyInfoStorageBase(ModuleDependencyKind::Clang),
pcmOutputPath(pcmOutputPath),
moduleMapFile(moduleMapFile),
contextHash(contextHash),
nonPathCommandLine(nonPathCommandLine),
fileDependencies(fileDependencies),
capturedPCMArgs(capturedPCMArgs) {}
ModuleDependencyInfoStorageBase *clone() const override {
return new ClangModuleDependencyStorage(*this);
}
static bool classof(const ModuleDependencyInfoStorageBase *base) {
return base->dependencyKind == ModuleDependencyKind::Clang;
}
};
/// Describes an placeholder Swift module dependency module stub.
///
/// This class is mostly an implementation detail for \c ModuleDependencyInfo.
class SwiftPlaceholderModuleDependencyStorage : public ModuleDependencyInfoStorageBase {
public:
SwiftPlaceholderModuleDependencyStorage(const std::string &compiledModulePath,
const std::string &moduleDocPath,
const std::string &sourceInfoPath)
: ModuleDependencyInfoStorageBase(ModuleDependencyKind::SwiftPlaceholder),
compiledModulePath(compiledModulePath),
moduleDocPath(moduleDocPath),
sourceInfoPath(sourceInfoPath) {}
ModuleDependencyInfoStorageBase *clone() const override {
return new SwiftPlaceholderModuleDependencyStorage(*this);
}
/// The path to the .swiftmodule file.
const std::string compiledModulePath;
/// The path to the .swiftModuleDoc file.
const std::string moduleDocPath;
/// The path to the .swiftSourceInfo file.
const std::string sourceInfoPath;
static bool classof(const ModuleDependencyInfoStorageBase *base) {
return base->dependencyKind == ModuleDependencyKind::SwiftPlaceholder;
}
};
// MARK: Module Dependency Info
/// Describes the dependencies of a given module.
///
/// The dependencies of a module include all of the source files that go
/// into that module, as well as any modules that are directly imported
/// into the module.
class ModuleDependencyInfo {
private:
std::unique_ptr<ModuleDependencyInfoStorageBase> storage;
ModuleDependencyInfo(std::unique_ptr<ModuleDependencyInfoStorageBase> &&storage)
: storage(std::move(storage)) { }
public:
ModuleDependencyInfo() = default;
ModuleDependencyInfo(const ModuleDependencyInfo &other)
: storage(other.storage->clone()) { }
ModuleDependencyInfo(ModuleDependencyInfo &&other) = default;
ModuleDependencyInfo &operator=(const ModuleDependencyInfo &other) {
storage.reset(other.storage->clone());
return *this;
}
ModuleDependencyInfo &operator=(ModuleDependencyInfo &&other) = default;
/// Describe the module dependencies for a Swift module that can be
/// built from a Swift interface file (\c .swiftinterface).
static ModuleDependencyInfo forSwiftInterfaceModule(
const std::string &moduleOutputPath,
const std::string &swiftInterfaceFile,
ArrayRef<std::string> compiledCandidates,
ArrayRef<StringRef> buildCommands,
ArrayRef<StringRef> extraPCMArgs,
StringRef contextHash,
bool isFramework) {
return ModuleDependencyInfo(
std::make_unique<SwiftInterfaceModuleDependenciesStorage>(
moduleOutputPath, swiftInterfaceFile, compiledCandidates, buildCommands,
extraPCMArgs, contextHash, isFramework));
}
/// Describe the module dependencies for a serialized or parsed Swift module.
static ModuleDependencyInfo forSwiftBinaryModule(
const std::string &compiledModulePath,
const std::string &moduleDocPath,
const std::string &sourceInfoPath,
bool isFramework) {
return ModuleDependencyInfo(
std::make_unique<SwiftBinaryModuleDependencyStorage>(
compiledModulePath, moduleDocPath, sourceInfoPath, isFramework));
}
/// Describe the main Swift module.
static ModuleDependencyInfo forSwiftSourceModule(ArrayRef<StringRef> extraPCMArgs) {
return ModuleDependencyInfo(
std::make_unique<SwiftSourceModuleDependenciesStorage>(extraPCMArgs));
}
/// Describe the module dependencies for a Clang module that can be
/// built from a module map and headers.
static ModuleDependencyInfo forClangModule(
const std::string &pcmOutputPath,
const std::string &moduleMapFile,
const std::string &contextHash,
const std::vector<std::string> &nonPathCommandLine,
const std::vector<std::string> &fileDependencies,
const std::vector<std::string> &capturedPCMArgs) {
return ModuleDependencyInfo(
std::make_unique<ClangModuleDependencyStorage>(
pcmOutputPath, moduleMapFile, contextHash,
nonPathCommandLine, fileDependencies, capturedPCMArgs));
}
/// Describe a placeholder dependency swift module.
static ModuleDependencyInfo forPlaceholderSwiftModuleStub(
const std::string &compiledModulePath,
const std::string &moduleDocPath,
const std::string &sourceInfoPath) {
return ModuleDependencyInfo(
std::make_unique<SwiftPlaceholderModuleDependencyStorage>(
compiledModulePath, moduleDocPath, sourceInfoPath));
}
/// Retrieve the module-level dependencies.
ArrayRef<std::string> getModuleDependencies() const {
return storage->moduleDependencies;
}
/// Whether the dependencies are for a Swift module: either Textual, Source, Binary, or Placeholder.
bool isSwiftModule() const;
/// Whether the dependencies are for a textual Swift module.
bool isSwiftInterfaceModule() const;
/// Whether the dependencies are for a textual Swift module.
bool isSwiftSourceModule() const;
/// Whether the dependencies are for a binary Swift module.
bool isSwiftBinaryModule() const;
/// Whether this represents a placeholder module stub
bool isSwiftPlaceholderModule() const;
/// Whether the dependencies are for a Clang module.
bool isClangModule() const;
ModuleDependencyKind getKind() const {
return storage->dependencyKind;
}
/// Retrieve the dependencies for a Swift textual-interface module.
const SwiftInterfaceModuleDependenciesStorage *getAsSwiftInterfaceModule() const;
/// Retrieve the dependencies for a Swift module.
const SwiftSourceModuleDependenciesStorage *getAsSwiftSourceModule() const;
/// Retrieve the dependencies for a binary Swift module.
const SwiftBinaryModuleDependencyStorage *getAsSwiftBinaryModule() const;
/// Retrieve the dependencies for a Clang module.
const ClangModuleDependencyStorage *getAsClangModule() const;
/// Retrieve the dependencies for a placeholder dependency module stub.
const SwiftPlaceholderModuleDependencyStorage *
getAsPlaceholderDependencyModule() const;
/// Add a dependency on the given module, if it was not already in the set.
void addModuleDependency(StringRef module,
llvm::StringSet<> *alreadyAddedModules = nullptr);
/// Add a dependency on the given module, if it was not already in the set.
void addModuleDependency(ImportPath::Module module,
llvm::StringSet<> *alreadyAddedModules = nullptr) {
addModuleDependency(module.front().Item.str(), alreadyAddedModules);
}
/// Add all of the module dependencies for the imports in the given source
/// file to the set of module dependencies.
void addModuleDependencies(const SourceFile &sf,
llvm::StringSet<> &alreadyAddedModules);
/// Get the bridging header.
Optional<std::string> getBridgingHeader() const;
/// Add a bridging header to a Swift module's dependencies.
void addBridgingHeader(StringRef bridgingHeader);
/// Add source files
void addSourceFile(StringRef sourceFile);
/// Add source files that the bridging header depends on.
void addBridgingSourceFile(StringRef bridgingSourceFile);
/// Add (Clang) module on which the bridging header depends.
void addBridgingModuleDependency(StringRef module,
llvm::StringSet<> &alreadyAddedModules);
/// Collect a map from a secondary module name to a list of cross-import
/// overlays, when this current module serves as the primary module.
llvm::StringMap<llvm::SmallSetVector<Identifier, 4>>
collectCrossImportOverlayNames(ASTContext &ctx, StringRef moduleName);
};
using ModuleDependencyID = std::pair<std::string, ModuleDependencyKind>;
using ModuleDependenciesVector = llvm::SmallVector<ModuleDependencyInfo, 1>;
using ModuleNameToDependencyMap = llvm::StringMap<ModuleDependencyInfo>;
using ModuleDependenciesKindMap =
std::unordered_map<ModuleDependencyKind,
ModuleNameToDependencyMap,
ModuleDependencyKindHash>;
using ModuleDependenciesKindRefMap =
std::unordered_map<ModuleDependencyKind,
llvm::StringMap<const ModuleDependencyInfo *>,
ModuleDependencyKindHash>;
// MARK: SwiftDependencyScanningService
/// A carrier of state shared among possibly multiple invocations of the dependency
/// scanner. Acts as a global cache of discovered module dependencies and
/// filesystem state. It is not to be queried directly, but is rather
/// meant to be wrapped in an instance of `ModuleDependenciesCache`, responsible
/// for recording new dependencies and answering cache queries in a given scan.
class SwiftDependencyScanningService {
/// Global cache contents specific to a specific scanner invocation context
struct ContextSpecificGlobalCacheState {
/// All cached module dependencies, in the order in which they were
/// encountered.
std::vector<ModuleDependencyID> AllModules;
/// Dependencies for modules that have already been computed.
/// This maps a dependency kind to a map of a module's name to a Dependency
/// object
ModuleDependenciesKindMap ModuleDependenciesMap;
};
/// The persistent Clang dependency scanner service
clang::tooling::dependencies::DependencyScanningService ClangScanningService;
/// The global file system cache.
Optional<
clang::tooling::dependencies::DependencyScanningFilesystemSharedCache>
SharedFilesystemCache;
/// All cached Swift source module dependencies, in the order in which they
/// were encountered
std::vector<ModuleDependencyID> AllSourceModules;
/// Dependencies for all Swift source-based modules discovered. Each one is
/// the main module of a prior invocation of the scanner.
ModuleNameToDependencyMap SwiftSourceModuleDependenciesMap;
/// A map from a String representing the target triple of a scanner invocation
/// to the corresponding cached dependencies discovered so far when using this
/// triple.
llvm::StringMap<std::unique_ptr<ContextSpecificGlobalCacheState>>
ContextSpecificCacheMap;
/// The current context hash configuration
Optional<std::string> CurrentContextHash;
/// The context hashes used by scanners using this cache, in the order in
/// which they were used
std::vector<std::string> AllContextHashes;
/// Retrieve the dependencies map that corresponds to the given dependency
/// kind.
ModuleNameToDependencyMap &getDependenciesMap(ModuleDependencyKind kind);
const ModuleNameToDependencyMap &
getDependenciesMap(ModuleDependencyKind kind) const;
public:
SwiftDependencyScanningService();
SwiftDependencyScanningService(const SwiftDependencyScanningService &) = delete;
SwiftDependencyScanningService &
operator=(const SwiftDependencyScanningService &) = delete;
virtual ~SwiftDependencyScanningService() {}
/// Query the service's filesystem cache
clang::tooling::dependencies::DependencyScanningFilesystemSharedCache &getSharedCache() {
assert(SharedFilesystemCache && "Expected a shared cache");
return *SharedFilesystemCache;
}
/// Query the service's filesystem cache
clang::tooling::dependencies::DependencyScanningFilesystemSharedCache &
getSharedFilesystemCache() {
assert(SharedFilesystemCache && "Expected a shared cache");
return *SharedFilesystemCache;
}
/// Wrap the filesystem on the specified `CompilerInstance` with a
/// caching `DependencyScanningWorkerFilesystem`
void overlaySharedFilesystemCacheForCompilation(CompilerInstance &Instance);
private:
/// Enforce clients not being allowed to query this cache directly, it must be
/// wrapped in an instance of `ModuleDependenciesCache`.
friend class ModuleDependenciesCache;
friend class ModuleDependenciesCacheDeserializer;
friend class ModuleDependenciesCacheSerializer;
friend class DependencyScanningTool;
/// Configure the current state of the cache to respond to queries
/// for the specified scanning context hash.
void configureForContextHash(std::string scanningContextHash);
/// Return context hashes of all scanner invocations that have used
/// this cache instance.
const std::vector<std::string> &getAllContextHashes() const {
return AllContextHashes;
}
/// Whether we have cached dependency information for the given module.
bool hasDependencies(StringRef moduleName,
Optional<ModuleDependencyKind> kind) const;
/// Return a pointer to the context-specific cache state of the current
/// scanning action.
ContextSpecificGlobalCacheState *getCurrentCache() const;
/// Return a pointer to the cache state of the specified context hash.
ContextSpecificGlobalCacheState *
getCacheForScanningContextHash(StringRef scanningContextHash) const;
/// Look for source-based module dependency details
Optional<ModuleDependencyInfo>
findSourceModuleDependency(StringRef moduleName) const;
/// Look for module dependencies for a module with the given name
///
/// \returns the cached result, or \c None if there is no cached entry.
Optional<ModuleDependencyInfo>
findDependencies(StringRef moduleName,
Optional<ModuleDependencyKind> kind) const;
/// Record dependencies for the given module.
const ModuleDependencyInfo *recordDependencies(StringRef moduleName,
ModuleDependencyInfo dependencies);
/// Update stored dependencies for the given module.
const ModuleDependencyInfo *updateDependencies(ModuleDependencyID moduleID,
ModuleDependencyInfo dependencies);
/// Reference the list of all module dependencies that are not source-based
/// modules (i.e. interface dependencies, binary dependencies, clang
/// dependencies).
const std::vector<ModuleDependencyID> &
getAllNonSourceModules(StringRef scanningContextHash) const {
auto contextSpecificCache =
getCacheForScanningContextHash(scanningContextHash);
return contextSpecificCache->AllModules;
}
/// Return the list of all source-based modules discovered by this cache
const std::vector<ModuleDependencyID> &getAllSourceModules() const {
return AllSourceModules;
}
};
// MARK: ModuleDependenciesCache
/// This "local" dependencies cache persists only for the duration of a given
/// scanning action, and wraps an instance of a `SwiftDependencyScanningService`
/// which may carry cached scanning information from prior scanning actions.
/// This cache maintains a store of references to all dependencies found within
/// the current scanning action (with their values stored in the global Cache).
class ModuleDependenciesCache {
private:
SwiftDependencyScanningService &globalScanningService;
/// References to data in `globalCache` for Swift dependencies and
/// `clangModuleDependencies` for Clang dependencies accimulated during
/// the current scanning action.
ModuleDependenciesKindRefMap ModuleDependenciesMap;
/// Name of the module under scan
std::string mainScanModuleName;
/// The context hash of the current scanning invocation
std::string scannerContextHash;
/// Set containing all of the Clang modules that have already been seen.
llvm::StringSet<> alreadySeenClangModules;
/// The Clang dependency scanner tool
clang::tooling::dependencies::DependencyScanningTool clangScanningTool;
/// Discovered Clang modules are only cached locally.
llvm::StringMap<ModuleDependenciesVector> clangModuleDependencies;
/// Retrieve the dependencies map that corresponds to the given dependency
/// kind.
llvm::StringMap<const ModuleDependencyInfo *> &
getDependencyReferencesMap(ModuleDependencyKind kind);
const llvm::StringMap<const ModuleDependencyInfo *> &
getDependencyReferencesMap(ModuleDependencyKind kind) const;
/// Local cache results lookup, only for modules which were discovered during
/// the current scanner invocation.
bool hasDependenciesLocalOnly(StringRef moduleName,
Optional<ModuleDependencyKind> kind) const;
/// Local cache results lookup, only for modules which were discovered during
/// the current scanner invocation.
Optional<const ModuleDependencyInfo *>
findDependenciesLocalOnly(StringRef moduleName,
Optional<ModuleDependencyKind> kind) const;
public:
ModuleDependenciesCache(SwiftDependencyScanningService &globalScanningService,
std::string mainScanModuleName,
std::string scanningContextHash);
ModuleDependenciesCache(const ModuleDependenciesCache &) = delete;
ModuleDependenciesCache &operator=(const ModuleDependenciesCache &) = delete;
public:
/// Whether we have cached dependency information for the given module.
bool hasDependencies(StringRef moduleName,
Optional<ModuleDependencyKind> kind) const;
/// Produce a reference to the Clang scanner tool associated with this cache
clang::tooling::dependencies::DependencyScanningTool& getClangScannerTool() {
return clangScanningTool;
}
llvm::StringSet<>& getAlreadySeenClangModules() {
return alreadySeenClangModules;
}
/// Look for module dependencies for a module with the given name
///
/// \returns the cached result, or \c None if there is no cached entry.
Optional<ModuleDependencyInfo>
findDependencies(StringRef moduleName,
Optional<ModuleDependencyKind> kind) const;
/// Record dependencies for the given module.
void recordDependencies(StringRef moduleName,
ModuleDependencyInfo dependencies);
/// Update stored dependencies for the given module.
void updateDependencies(ModuleDependencyID moduleID,
ModuleDependencyInfo dependencies);
const std::vector<ModuleDependencyID> &getAllSourceModules() const {
return globalScanningService.getAllSourceModules();
}
StringRef getMainModuleName() const {
return mainScanModuleName;
}
};
} // namespace swift
#endif /* SWIFT_AST_MODULE_DEPENDENCIES_H */