When generating a module interface, emit `#if` around any declarations
that are tied to specific, named language features. This allows module
interfaces to be processed by older Swift compilers that do not
support these newer features, such as async/await or actors.
The amount of effort required to correctly handle a new kind of
feature varies somewhat drastically based on the feature itself. The
"simple" case is where a particular declaration can only exist if a
feature is available. For example, and `async` declaration is fairly
easy to handle; a `@_marker` protocol's conformances are not.
Fixes rdar://73326633.
This option allows the compiler to retry opening an input file if the previous
opening returns an error of bad file descriptor. Swift-driver will set this
argument in certain circumstances to walk-around such error.
rdar://73157185
Switch from a string core to a 128-bit integral core. This should make
Fingerprints much cheaper to copy around and sets us up for a future
where we can provide alternative implementations of the ambient hashing
algorithm.
rdar://72313506
Introducing new entry-points that can be used from both Driver and Frontend clients, using an intermediary new type: `DetailedMessagePayload`, when needed.
Starting at a crude -1000, each invocation primary input will get its own unique quasi-Pid.
Invocations with only one primary (non-batch) will get a real OS Pid.
The selection of the constant starting point matches what the driver does when outputting its parseable output.
We're going to play a dirty, dirty trick - but it'll make our users'
lives better in the end so stick with me here.
In order to build up an incremental compilation, we need two sources of
dependency information:
1) "Priors" - Swiftdeps with dependency information from the past
build(s)
2) "Posteriors" - Swiftdeps with dependencies from after we rebuild the
file or module or whatever
With normal swift files built in incremental mode, the priors are given by the
swiftdeps files which are generated parallel to a swift file and usually
placed in the build directory alongside the object files. Because we
have entries in the output file map, we can always know where these
swiftdeps files are. The priors are integrated by the driver and then
the build is scheduled. As the build runs and jobs complete, their
swiftdeps are reloaded and re-integrated. The resulting changes are then
traversed and more jobs are scheduled if necessary. These give us the
posteriors we desire.
A module flips this on its head. The swiftdeps information serialized
in a module functions as the *posterior* since the driver consuming the
module has no way of knowing how to rebuild the module, and because its
dependencies are, for all intents and purposes, fixed in time. The
missing piece of the puzzle is the priors. That is, we need some way of
knowing what the "past" interface of the module looked like so we can
compare it to the "present" interface. Moreover, we need to always know
where to look for these priors.
We solve this problem by serializing a file alongside the build record:
the "external" build record. This is given by a... creative encoding
of multiple source file dependency graphs into a single source file
dependency graph. The rough structure of this is:
SourceFile => interface <BUILD_RECORD>.external
| - Incremental External Dependency => interface <MODULE_1>.swiftmodule
| | - <dependency> ...
| | - <dependency> ...
| | - <dependency> ...
| - Incremental External Dependency => interface <MODULE_2>.swiftmodule
| | - <dependency> ...
| | - <dependency> ...
| - Incremental External Dependency => interface <MODULE_3>.swiftmodule
| - ...
Sorta, `cat`'ing a bunch of source file dependency graphs together but
with incremental external dependency nodes acting as glue.
Now for the trick:
We have to unpack this structure and integrate it to get our priors.
This is easy. The tricky bit comes in integrate itself. Because the
top-level source file node points directly at the external build record,
not the original swift modules that defined these dependency nodes, we
swap the key it wants to use (the external build record) for the
incremental external dependency acting as the "parent" of the dependency
node. We do this by following the arc we carefully laid down in the
structure above.
For rdar://69595010
Goes a long way towards rdar://48955139, rdar://64238133
When a completion-handler parameter has text before, e.g.,
"WithCompletionHandler", put the extra text on the base name rather
than the corresponding parameter. This ensures that we don't lose the
detail from the text, but always put it into a consistent place.
Extend the set of completion-handler names we look for to infer an
`async` import of an Objective-C method, which includes:
* (with)CompletionBlock
* (with)reply
* (with)replyTo
both as parameter names and as base name suffixes.
A fingerprint is a stable hash of a particular piece of compiler data. This formalizes the stable notion of identity that the dependency trackers use for type body fingerprints in iterable decl contexts and the file-level interface hash
When a completion handler parameter has a selector piece that ends with
"WithCompletion(Handler)", prepend the text before that suffix to the
base name or previous argument label, as appropriate. This ensures that
we don't lose information from the name, particularly with delegate names.