Fast dependency scanning for Swift

Implement a new "fast" dependency scanning option,
`-scan-dependencies`, in the Swift frontend that determines all
of the source file and module dependencies for a given set of
Swift sources. It covers four forms of modules:

1) Swift (serialized) module files, by reading the module header
2) Swift interface files, by parsing the source code to find imports
3) Swift source modules, by parsing the source code to find imports
4) Clang modules, using Clang's fast dependency scanning tool

A single `-scan-dependencies` operation maps out the full
dependency graph for the given Swift source files, including all
of the Swift and Clang modules that may need to be built, such
that all of the work can be scheduled up front by the Swift
driver or any other build system that understands this
option. The dependency graph is emitted as JSON, which can be
consumed by these other tools.
This commit is contained in:
Doug Gregor
2020-01-04 22:49:54 -08:00
parent 46703b4ba1
commit 33cdd61835
36 changed files with 1454 additions and 10 deletions

View File

@@ -1537,6 +1537,14 @@ void Driver::buildOutputInfo(const ToolChain &TC, const DerivedArgList &Args,
OI.CompilerMode = OutputInfo::Mode::SingleCompile;
break;
case options::OPT_scan_dependencies:
OI.CompilerOutputType = file_types::TY_JSONDependencies;
// We want the imported modules from the module as a whole, not individual
// files, so let's do it in one invocation rather than having to collate
// later.
OI.CompilerMode = OutputInfo::Mode::SingleCompile;
break;
case options::OPT_index_file:
OI.CompilerMode = OutputInfo::Mode::SingleCompile;
OI.CompilerOutputType = file_types::TY_IndexData;
@@ -1989,6 +1997,7 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
case file_types::TY_PrivateSwiftModuleInterfaceFile:
case file_types::TY_SwiftCrossImportDir:
case file_types::TY_SwiftOverlayFile:
case file_types::TY_JSONDependencies:
// We could in theory handle assembly or LLVM input, but let's not.
// FIXME: What about LTO?
Diags.diagnose(SourceLoc(), diag::error_unexpected_input_file,