This refactoring allows us to drop ModuleInterfaceLoader when explicit modules
are enabled. Before this change, the dependencies scanner needs the loader to be
present to access functionalities like collecting prebuilt module candidates.
These inputs were previously modeled as Swift files, which would lead to bizarre situations where parts of the pipeline expecting Swift inputs actually wound up parsing Objective-C.
We need ClangImporterOptions to be persistent for several scenarios: (1)
when creating a sub-ASTContext to build Swift modules from interfaces; and
(2) when creating a new Clang instance to invoke Clang dependencies scanner.
This change is NFC.
Try to impose a simple structure that splits performing actions from the
pre and post-pipeline conditions. Wherever actions would take more than
a simple return, split them into functions. Refine functions that
perform effects to return status codes when they fail. Finally,
delineate functions that need semantic analysis from those that do not.
Overall this should be NFC.
In order to avoid accidentally implicitly loading modules that are expected but were not provided as explicit inputs.
- Use either SerializedModuleLoader or ExplicitSwiftModuleLoader for loading of partial modules, depending on whether we are in Explicit Module Build or Implicit Module Build mode.
Previously we would only link `.sib` partial
modules in SILGen, with other kinds of serialized
ASTs being linked just before the SILOptimizer if
`-sil-merge-partial-modules` was specified.
However linking them always seems to be the desired
behaviour, so adjust SILGen to link SIL for all
serialized AST inputs.
For the explicit module mode, swift-driver uses -compile-module-from-interface to
generate modules from interfaces found by the dependency scanner. However, we don't
need to build the binary module if up-to-date modules are available, either adjacent
to the interface file or in the prebuilt module cache directory. This patch teaches
dependencies scanner to report these ready-to-use binary modules.
Expand the FrontendOptions to allow the enabling
of the dependency tracker for non-system
dependencies, and switch the previous clients of
`createDependencyTracker` over to using this
option. This ensures that the dependency tracker
is now set only during `CompilerInstance::setup`.
Instead of taking paths of Swift module files from front-end command line
arguments, we should take a JSON file specifying details of explicit modules.
The advantages is (1) .swiftdoc and .swiftsourceinfo can be associated
with a .swiftmodule file, and (2) module names are explicitly used as
keys in the JSON input so we don't need to eagerly deserialize a .swiftmodule
file to collect the module name.
There's no reason clients need to be able to access this data directly.
It obscures where module loading is actually happening, and makes it too
easy to accidentally register a module with the wrong identifier in the
context.
Hide the registration operations behind opaque accessors.
We were not using the primary benefits of an intrusive list, namely the
ability to insert or remove from the middle of the list, so let's switch
to a plain vector. This also avoids linked-list pointer chasing.
Now that it no longer needs to handle the
parse-only case, we can simplify things by having
`performSema` call into
`performParseAndResolveImportsOnly`.
Most clients were only using it to populate the
main module with files, which is now done by
`getMainModule`. Instead, they can now just rely
on parsing happening lazily.
Move into `performEndOfPipelineActions`, and move
the call up a bit in `performCompile` to make sure
it gets called even for a parse-only invocation.
Unfortunately this requires carving out an
exception for `-emit-imported-modules`, which can
load modules.
Rather than waiting until one of the performXXX
methods are called, make sure all the main module's
files have been populated up-front by
`getMainModule`.
Lift the `DisablePoundIfEvaluation` parsing option
into `LangOptions` to subsume the need for the
`EvaluateConditionals` parameter, and sink the
computation of `CanDelayBodies` down into
`createSourceFileForMainModule`.
To support -disable-implicit-swift-modules, the explicitly built modules
are passed down as compiler arguments. We need this new module loader to
handle these modules.
This patch also stops ModuleInterfaceLoader from building module from interface
when -disable-implicit-swift-modules is set.
Sink the `BuildSyntaxTree` and
`CollectParsedTokens` bits into
`SourceFile::ParsingFlags`, with a static method
to get the parsing options from the lang opts.
Also add a parsing flag for enabling the interface
hash, which can be used instead of calling
`enableInterfaceHash`.
Rather than replacing the code completion file
on the `CompilerInstance` whenever we do a cached
top-level completion, let's set a new main module
instead.
This allows us to properly update the
`LoadedModules` map, and allows the retrieval of
the code completion file to be turned into a
request.
Remove the `PrimarySourceFiles` vector from the
frontend and replace it with a request on
ModuleDecl that retrieves the primary files for
the main module.
This is in preparation for having
`CompilerInstance::getMainModule` automatically
populate the main module with files when queried.
Rather than trying to continue the compilation
with an empty main module, let's bail out early if
we expect an implicit stdlib import and fail to
load in the stdlib.
Rather than adding a ModuleFile to a parent module
and then removing it afterwards if it fails to
load, let's wait until we've loaded the file before
deciding to add it to the parent module. This then
allows us to get rid of `ModuleDecl::removeFile`.
In addition, push down the calls to `addFile` into
the callers of `loadAST` in preparation for
`addFile` being replaced with a one-time-only call
to a `setFiles` method.