Add a bit to the module to determine whether the dependency’s stored bit pattern is a hash or an mtime.
Prebuilt modules store a hash of their dependencies because we can’t be sure their dependencies will have the same modtime as when they were built.
Previously, we included the PCH hash components in the cache key. While they didn’t do any harm, they didn’t contribute any unique information about the module in question.
Additionally, passing the effective language version in means that each dependency that uses a different -swift-version would re-compile all of its dependencies. This is unfortunate, as that means the standard library is recompiled potentially several times.
Hashing the contents of the interface files is overkill. In practice, size and last modification time are enough to determine if a file has changed on disk, and therefore should be rebuilt.
There's a class of errors in Serialization called "circularity
issues", where declaration A in file A.swift depends on declaration B
in file B.swift, and B also depends on A. In some cases we can manage
to type-check each of these files individually due to the laziness of
'validateDecl', but then fail to merge the "partial modules" generated
from A.swift and B.swift to form a single swiftmodule for the library
(because deserialization is a little less lazy for some things). A
common case of this is when at least one of the declarations is
nested, in which case a lookup to find that declaration needs to load
all the members of the parent type. This gets even worse when the
nested type is defined in an extension.
This commit sidesteps that issue specifically for nested types by
creating a top-level, per-file table of nested types in the "partial
modules". When a type is in the same module, we can then look it up
/without/ importing all other members of the parent type.
The long-term solution is to allow accessing any members of a type
without having to load them all, something we should support not just
for module-merging while building a single target but when reading
from imported modules as well. This should improve both compile time
and memory usage, though I'm not sure to what extent. (Unfortunately,
too many things still depend on the whole members list being loaded.)
Because this is a new code path, I put in a switch to turn it off:
frontend flag -disable-serialization-nested-type-lookup-table
https://bugs.swift.org/browse/SR-3707 (and possibly others)
That's how everything behaved anyway. Might as well make it explicit and
stop special-casing it.
I've left in compatibility for modules built with older compilers so that
people using the OS toolchains aren't immediately unable to debug their apps.
As soon as we change the module format in a more significant way, I can take
this out.
Groundwork for rdar://problem/21254367; see next commit.
Swift SVN r29437
...so that the debugger has the best possible chance of being able to load
the app properly.
We don't do this for frameworks today because we don't want to leak this
information into the public module; once we have a distinction between
"the module that ships with the framework" and "the module that goes into
the debug info" we can do this for frameworks as well.
Part of rdar://problem/17670778
Swift SVN r25204
There's also a testing option, -serialize-debugging-options, to force this
extra info to be serialized even for library targets. In the long run we'll
probably write out this information for all targets, but strip it out of
the "public module" when a framework is built. (That way it ends up in the
debug info's copy of the module.)
Incidentally, this commit includes the ability to add search paths to the
Clang importer on the fly, which is most of rdar://problem/16347147.
Unfortunately there's no centralized way to add search paths to both Clang
/and/ Swift at the moment.
Part of rdar://problem/17670778
Swift SVN r24545
Previously, we depended on whether or not a serialized module was located
within a framework bundle to consider whether or not it may have a "Clang
half". However, LLDB loads serialized modules from dSYM bundles. Rather
than try to figure out if such a module is "really" a framework, just track
whether the original module was built with -import-underlying-module. If so,
consider the underlying Clang module to be re-exported.
rdar://problem/18099523
Swift SVN r21544