Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions include/swift/IRGen/Linking.h
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,10 @@ class LinkEntity {
// These are both type kinds and protocol-conformance kinds.
// TYPE KINDS: BEGIN {{

/// A SIL differentiability witness. The pointer is a
/// SILDifferentiabilityWitness*.
DifferentiabilityWitness,

/// A lazy protocol witness accessor function. The pointer is a
/// canonical TypeBase*, and the secondary pointer is a
/// ProtocolConformance*.
Expand All @@ -460,10 +464,6 @@ class LinkEntity {
/// ProtocolConformance*.
ProtocolWitnessTableLazyCacheVariable,

/// A SIL differentiability witness. The pointer is a
/// SILDifferentiabilityWitness*.
DifferentiabilityWitness,

// Everything following this is a type kind.

/// A value witness for a type.
Expand Down
47 changes: 25 additions & 22 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4023,38 +4023,41 @@ IRGenModule::getAddrOfLLVMVariable(LinkEntity entity,
auto var = createVariable(*this, link, definitionType,
entity.getAlignment(*this), DbgTy);

// @escaping () -> ()
// NOTE: we explicitly desugar the `Void` type for the return as the test
// suite makes assumptions that it can emit the value witness table without a
// standard library for the target. `Context.getVoidType()` will attempt to
// lookup the `Decl` before returning the canonical type. To workaround this
// dependency, we simply desugar the `Void` return type to `()`.
static CanType kAnyFunctionType =
FunctionType::get({}, Context.TheEmptyTupleType,
ASTExtInfo{})->getCanonicalType();
auto isZeroParamFunctionType = [this](Type t) -> bool {
if (auto *funcTy = t->getAs<FunctionType>()) {
return (funcTy->getParams().size() == 0 &&
funcTy->getResult()->isEqual(Context.TheEmptyTupleType));
}

return false;
};

// Adjust the linkage for the well-known VWTs that are strongly defined
// in the runtime.
//
// We special case the "AnyFunctionType" here as this type is referened
// We special case the "AnyFunctionType" here as this type is referenced
// inside the standard library with the definition being in the runtime
// preventing the normal detection from identifying that this is module
// local.
//
// If we are statically linking the standard library, we need to internalise
// the symbols.
if (getSwiftModule()->isStdlibModule() ||
(Context.getStdlibModule() &&
Context.getStdlibModule()->isStaticLibrary()))
if (entity.isTypeKind() &&
(IsWellKnownBuiltinOrStructralType(entity.getType()) ||
entity.getType() == kAnyFunctionType))
if (auto *GV = dyn_cast<llvm::GlobalValue>(var))
if (GV->hasDLLImportStorageClass())
ApplyIRLinkage({llvm::GlobalValue::ExternalLinkage,
llvm::GlobalValue::DefaultVisibility,
llvm::GlobalValue::DefaultStorageClass})
.to(GV);
if (auto *GV = dyn_cast<llvm::GlobalValue>(var)) {
if (GV->hasDLLImportStorageClass()) {
if (getSwiftModule()->isStdlibModule() ||
(Context.getStdlibModule() &&
Context.getStdlibModule()->isStaticLibrary())) {
if (entity.isTypeKind() &&
(isWellKnownBuiltinOrStructuralType(entity.getType()) ||
isZeroParamFunctionType(entity.getType()))) {
ApplyIRLinkage({llvm::GlobalValue::ExternalLinkage,
llvm::GlobalValue::DefaultVisibility,
llvm::GlobalValue::DefaultStorageClass})
.to(GV);
}
}
}
}

// Install the concrete definition if we have one.
if (definition && definition.hasInit()) {
Expand Down
4 changes: 2 additions & 2 deletions lib/IRGen/IRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1411,13 +1411,13 @@ llvm::Module *IRGenModule::getModule() const {
return ClangCodeGen->GetModule();
}

bool IRGenModule::IsWellKnownBuiltinOrStructralType(CanType T) const {
bool IRGenModule::isWellKnownBuiltinOrStructuralType(CanType T) const {
if (T == Context.TheEmptyTupleType || T == Context.TheNativeObjectType ||
T == Context.TheBridgeObjectType || T == Context.TheRawPointerType ||
T == Context.getAnyObjectType())
return true;

if (auto IntTy = dyn_cast_or_null<BuiltinIntegerType>(T)) {
if (auto IntTy = dyn_cast<BuiltinIntegerType>(T)) {
auto Width = IntTy->getWidth();
if (Width.isPointerWidth())
return true;
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/IRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -1196,7 +1196,7 @@ class IRGenModule {

ClassMetadataStrategy getClassMetadataStrategy(const ClassDecl *theClass);

bool IsWellKnownBuiltinOrStructralType(CanType type) const;
bool isWellKnownBuiltinOrStructuralType(CanType type) const;

private:
TypeConverter &Types;
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/MetadataRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3664,7 +3664,7 @@ namespace {
//
// TODO: If a nominal type is in the same source file as we're currently
// emitting, we would be able to see its value witness table.
if (IGF.IGM.IsWellKnownBuiltinOrStructralType(t))
if (IGF.IGM.isWellKnownBuiltinOrStructuralType(t))
return emitFromValueWitnessTable(t);

// If the type is a singleton aggregate, the field's layout is equivalent
Expand Down