mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
IRGen: Deserialize SIL witness tables and shared-linkage definitions by need.
Code may end up indirectly using a witness table for a Clang-imported type by inlining code that used the conformance from another module, in which case we need to ensure we have a local definition at hand in the inlining module so we can have something to link against independently. This needs to be fixed from both sides: - During serialization, serialize not only witness tables from the current module, but from Clang-imported modules too, so that their definitions can be used by other modules that inline code from the current module - During IRGen, when we emit a reference to a SILWitnessTable or SILFunction declaration with shared linkage, attempt to deserialize the definition on demand Fixes rdar://problem/38687726.
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#include "swift/IRGen/Linking.h"
|
||||
#include "swift/Runtime/RuntimeFnWrappersGen.h"
|
||||
#include "swift/Runtime/Config.h"
|
||||
#include "swift/SIL/FormalLinkage.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/Basic/CharInfo.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
@@ -658,6 +659,9 @@ llvm::Module *IRGenModule::releaseModule() {
|
||||
}
|
||||
|
||||
bool IRGenerator::canEmitWitnessTableLazily(SILWitnessTable *wt) {
|
||||
if (LazilyEmittedWitnessTables.count(wt))
|
||||
return true;
|
||||
|
||||
if (Opts.UseJIT)
|
||||
return false;
|
||||
|
||||
@@ -685,6 +689,21 @@ void IRGenerator::addLazyWitnessTable(const ProtocolConformance *Conf) {
|
||||
LazilyEmittedWitnessTables.insert(wt).second) {
|
||||
LazyWitnessTables.push_back(wt);
|
||||
}
|
||||
// Shared-linkage protocol conformances may not have been deserialized yet
|
||||
// if they were used by inlined code. See if we can deserialize it now.
|
||||
} else {
|
||||
auto linkage =
|
||||
getLinkageForProtocolConformance(Conf->getRootNormalConformance(),
|
||||
ForDefinition);
|
||||
if (hasSharedVisibility(linkage)) {
|
||||
SIL.createWitnessTableDeclaration(const_cast<ProtocolConformance*>(Conf),
|
||||
linkage);
|
||||
SILWitnessTable *wt = SIL.lookUpWitnessTable(Conf);
|
||||
if (wt && wt->isDefinition()
|
||||
&& LazilyEmittedWitnessTables.insert(wt).second) {
|
||||
LazyWitnessTables.push_back(wt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user