diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h index ef309be45f0a4..7c8d656675930 100644 --- a/include/swift/IRGen/Linking.h +++ b/include/swift/IRGen/Linking.h @@ -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*. @@ -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. diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index 7188bc566a556..9eca835e4c1a9 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -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()) { + 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(var)) - if (GV->hasDLLImportStorageClass()) - ApplyIRLinkage({llvm::GlobalValue::ExternalLinkage, - llvm::GlobalValue::DefaultVisibility, - llvm::GlobalValue::DefaultStorageClass}) - .to(GV); + if (auto *GV = dyn_cast(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()) { diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp index 47827766f9833..7d236b2307aae 100644 --- a/lib/IRGen/IRGenModule.cpp +++ b/lib/IRGen/IRGenModule.cpp @@ -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(T)) { + if (auto IntTy = dyn_cast(T)) { auto Width = IntTy->getWidth(); if (Width.isPointerWidth()) return true; diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h index c2c86292b540f..9f41ac8cc4f00 100644 --- a/lib/IRGen/IRGenModule.h +++ b/lib/IRGen/IRGenModule.h @@ -1196,7 +1196,7 @@ class IRGenModule { ClassMetadataStrategy getClassMetadataStrategy(const ClassDecl *theClass); - bool IsWellKnownBuiltinOrStructralType(CanType type) const; + bool isWellKnownBuiltinOrStructuralType(CanType type) const; private: TypeConverter &Types; diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp index 92c10012361c4..9018108cb6e3c 100644 --- a/lib/IRGen/MetadataRequest.cpp +++ b/lib/IRGen/MetadataRequest.cpp @@ -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