To help consolidate our various types describing imports, this commit moves the following types and methods to Import.h:
* ImplicitImports
* ImplicitStdlibKind
* ImplicitImportInfo
* ModuleDecl::ImportedModule
* ModuleDecl::OrderImportedModules (as ImportedModule::Order)
* ModuleDecl::removeDuplicateImports() (as ImportedModule::removeDuplicates())
* SourceFile::ImportFlags
* SourceFile::ImportOptions
* SourceFile::ImportedModuleDesc
This commit is large and intentionally kept mechanical—nothing interesting to see here.
Cross-Module incremental dependencies are a new experimental mode of the Swift driver and frontend. Through a tight partnership between the two, we enable the driver to have far greater visibility into the dependency structure of a Swift module.
Rather than invent a new model, we have chosen to extend the existing incremental compilation model that works for a single module to multiple modules. To do this, we need the frontend to emit Swift dependencies in a form the driver can consume. We could emit these metadata in the form of an extra supplementary output that summarizes the contents of a generated module. However, this approach comes with a number of downsides:
- It requires additional integration with the build system
- It assumes swiftmodule files will be consumed directly from the build directory; they are not
- It incorrectly assumes a swiftmodule has but one interface. Taken in aggregate, a swiftmodule directory has one interface *per triple*
Given this, the approach we take here is to encode these dependencies directly into the swiftmodule file itself. When frontends load these souped-up incremental swiftmodule files, they record in their own swiftdeps files that they depend on an incremental swiftmodule. Upon the next build, the driver is then able to read that module file, extract the swiftdeps information from it, and use it to influence the way it schedules jobs.
The sum total is that we neatly extend the intra-module case of incremental builds to the inter-module case by treating swiftmodule inputs not as opaque entities, but as "big ol' flat Swift files" that just export an interface like any other Swift file within the module. As a further optimization, and because clients literally cannot observe this aspect of the incremental build, we only serialize the provides (the "defs" side of a "use-def" edge) when emitting swiftdeps metadata into swiftmodule files.
rdar://69595010
Adjust the serialized module loader to allow directory layouts for the
Swift module on non-Darwin targets, unifying the layout across all the
platforms. It also eases cross-architecture and cross-platform
development by having the same layout, which can enable more similar
flag usage.
* Add properties to ModuleFile which holds information from the control
block.
* 'ExtendedValidationInfo' parameter for 'ModuleFileSharedCore::load()'
cannot be 'nullptr'. Make it non-defaulted Rvalue reference.
'ModuleInterfacePath' is passed as 'StringRef' that memory used to
reside in ASTContext. But 'ModuleFileSharedCore' should be 'ASTContext'
independent. So copy it using its own allocator.
In the fast dependency scanner, depending on whether a module intrface was found via the import search path or framework search path, encode into the dependency graph Swift module details, whether a given module is a framework.
Introduce a new frontend flag -enable-volatile-modules to trigger
loading swiftmodule files as volatile and avoid using mmap. Revert the
default behavior to using mmap.
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.
Avoid mmaping swiftmodule files to hopefully fix issues seen when
building many Swift projects in parallel on NFS. This only affects
loading ModuleFile, it doesn't affect scanning swiftmodule for
dependecies which are still handled as non-volatile.
rdar://63755989
The difference with `ModuleFile` is that `ModuleFileSharedCore` provides immutable data and is independent of a particular ASTContext.
It is designed to be able to be shared across multiple `ModuleFile`s of different `ASTContext`s in a thread-safe manner.
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.
This makes it easier to specify OptionSet arguments.
Also modify appropriate uses of ModuleDecl::ImportFilter to take
advantage of the new constructor.
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.
```
class Generic<T> {
@objc dynamic func method() {}
}
extension Generic {
@_dynamicReplacement(for:method())
func replacement() {}
}
```
The standard mechanism of using Objective-C categories for dynamically
replacing @objc methods in generic classes does not work.
Instead we mark the native entry point as replaceable.
Because this affects all @objc methods in generic classes (whether there
is a replacement or not) by making the native entry point
`[dynamically_replaceable]` (regardless of optimization mode) we guard this by
the -enable-implicit-dynamic flag because we are late in the release cycle.
* Replace isNativeDynamic and isObjcDynamic by calls to shouldUse*Dispatch and
shouldUse*Replacement
This disambiguates between which dispatch method we should use at call
sites and how these methods should implement dynamic function
replacement.
* Don't emit the method entry for @_dynamicReplacement(for:) of generic class
methods
There is not way to call this entry point since we can't generate an
objective-c category for generic classes.
rdar://63679357
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.
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.
Using a SetVector fixes an issue where many source files imported the
same SPI group from the same module, the emitted private textual
interfaces superfluously repeated the `@_spi` attribute on the import.
rdar://problem/63681845
Permit the directory style `.swiftmodule` on non-Apple targets. This
allows all platforms to use the directory layout enabling
multi-architecture SDKs. This not only unifies the layout of the SDK
across the various targets, it also enables Windows to have a single
unified SDK.
The complexity here is due to the compatibility for older layouts. This
change does not break compatibility on Linux/Android/Windows for the old
style layout.