[Serialization] Delay all actions in the same module together. (#8123)

Back in December DougG added code to delay the formation of generic
environments until all declarations from a particular module had been
deserialized, to avoid circular dependencies caused by too-eager
deserialization of protocol members. This worked great for fully-built
modules, but still had some problems with module merging, the phase of
multi-file compilation where the "partial" swiftmodules that
correspond to each source file in a target are loaded and remitted as
a single swiftmodule. Fix this by picking one of the partial
swiftmodules as the representative one for delayed actions, and wait
until deserialization is complete for /all/ of the serialized ASTs in
the same target to form the generic environments.

rdar://problem/30984417
This commit is contained in:
Jordan Rose
2017-03-16 15:22:06 -07:00
committed by GitHub
parent e78445b437
commit a8e4e72270
10 changed files with 62 additions and 19 deletions

View File

@@ -83,6 +83,9 @@ class ModuleFile : public LazyMemberLoader {
/// Declaration contexts with delayed generic environments, which will be
/// completed as a pending action.
///
/// This should only be used on the module returned by
/// getModuleFileForDelayedActions().
///
/// FIXME: This is needed because completing a generic environment can
/// require the type checker, which might be gone if we delay generic
/// environments too far. It is a hack.
@@ -93,7 +96,8 @@ class ModuleFile : public LazyMemberLoader {
ModuleFile &MF;
public:
DeserializingEntityRAII(ModuleFile &MF) : MF(MF) {
DeserializingEntityRAII(ModuleFile &mf)
: MF(mf.getModuleFileForDelayedActions()) {
++MF.NumCurrentDeserializingEntities;
}
~DeserializingEntityRAII() {
@@ -108,6 +112,13 @@ class ModuleFile : public LazyMemberLoader {
};
friend class DeserializingEntityRAII;
/// Picks a specific ModuleFile instance to serve as the "delayer" for the
/// entire module.
///
/// This is usually \c this, but when there are partial swiftmodules all
/// loaded for the same module it may be different.
ModuleFile &getModuleFileForDelayedActions();
/// Finish any pending actions that were waiting for the topmost entity to
/// be deserialized.
void finishPendingActions();