From 362a25ae84ca4f56b4dfb810b6f9ecc438c0439a Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Wed, 15 Jan 2020 16:15:34 -0800 Subject: [PATCH 01/10] [AST] Support SILFunctionType/SILBlockStorageType in ClangTypeConverter. This translation is a pre-requisite to storing Clang types in SILFunctionType. --- lib/AST/ClangTypeConverter.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/AST/ClangTypeConverter.cpp b/lib/AST/ClangTypeConverter.cpp index d4ccea512f069..2a08f78fb282e 100644 --- a/lib/AST/ClangTypeConverter.cpp +++ b/lib/AST/ClangTypeConverter.cpp @@ -576,12 +576,19 @@ clang::QualType ClangTypeConverter::visitFunctionType(FunctionType *type) { } clang::QualType ClangTypeConverter::visitSILFunctionType(SILFunctionType *type) { - llvm::report_fatal_error("Expected only AST types but found a SIL function."); + // We must've already computed it before if applicable. + return clang::QualType(type->getClangTypeInfo().getType(), 0); } clang::QualType ClangTypeConverter::visitSILBlockStorageType(SILBlockStorageType *type) { - llvm::report_fatal_error("Expected only AST types but found a SIL block."); + // We'll select (void)(^)(). This isn't correct for all blocks, but block + // storage type should only be converted for function signature lowering, + // where the parameter types do not matter. + auto &clangCtx = ClangASTContext; + auto fnTy = clangCtx.getFunctionNoProtoType(clangCtx.VoidTy); + auto blockTy = clangCtx.getBlockPointerType(fnTy); + return clangCtx.getCanonicalType(blockTy); } clang::QualType From c890cdd1a379db55e51d7ec8657d55b6dc2e7ba4 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Mon, 27 Jul 2020 22:01:54 -0700 Subject: [PATCH 02/10] [AST] Add functionality for computing Clang types for SIL functions. --- include/swift/AST/ASTContext.h | 14 ++++++++++ lib/AST/ASTContext.cpp | 24 ++++++++++++---- lib/AST/ClangTypeConverter.cpp | 51 ++++++++++++++++++++++++++++++++++ lib/AST/ClangTypeConverter.h | 5 ++++ lib/IRGen/GenClangType.cpp | 10 +++---- 5 files changed, 94 insertions(+), 10 deletions(-) diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h index 9281ebcf55c2b..e3ecfbb158dfb 100644 --- a/include/swift/AST/ASTContext.h +++ b/include/swift/AST/ASTContext.h @@ -62,6 +62,7 @@ namespace swift { class BoundGenericType; class ClangModuleLoader; class ClangNode; + class ClangTypeConverter; class ConcreteDeclRef; class ConstructorDecl; class Decl; @@ -586,6 +587,10 @@ class ASTContext final { Type getBridgedToObjC(const DeclContext *dc, Type type, Type *bridgedValueType = nullptr) const; +private: + ClangTypeConverter &getClangTypeConverter(); + +public: /// Get the Clang type corresponding to a Swift function type. /// /// \param params The function parameters. @@ -595,6 +600,15 @@ class ASTContext final { getClangFunctionType(ArrayRef params, Type resultTy, FunctionTypeRepresentation trueRep); + /// Get the canonical Clang type corresponding to a SIL function type. + /// + /// SIL analog of \c ASTContext::getClangFunctionType . + const clang::Type * + getCanonicalClangFunctionType( + ArrayRef params, Optional result, + const SILFunctionType::ExtInfo incompleteExtInfo, + SILFunctionType::Representation trueRep); + /// Get the Swift declaration that a Clang declaration was exported from, /// if applicable. const Decl *getSwiftDeclForExportedClangDecl(const clang::Decl *decl); diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 633527ccf7735..b8a0f69ccd747 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -4457,16 +4457,30 @@ Type ASTContext::getBridgedToObjC(const DeclContext *dc, Type type, return Type(); } -const clang::Type * -ASTContext::getClangFunctionType(ArrayRef params, - Type resultTy, - FunctionTypeRepresentation trueRep) { +ClangTypeConverter &ASTContext::getClangTypeConverter() { auto &impl = getImpl(); if (!impl.Converter) { auto *cml = getClangModuleLoader(); impl.Converter.emplace(*this, cml->getClangASTContext(), LangOpts.Target); } - return impl.Converter.getValue().getFunctionType(params, resultTy, trueRep); + return impl.Converter.getValue(); +} + +const clang::Type * +ASTContext::getClangFunctionType(ArrayRef params, + Type resultTy, + FunctionTypeRepresentation trueRep) { + return getClangTypeConverter().getFunctionType(params, resultTy, trueRep); +} + +const clang::Type * +ASTContext::getCanonicalClangFunctionType( + ArrayRef params, + Optional result, + SILFunctionType::ExtInfo incompleteExtInfo, + SILFunctionType::Representation trueRep) { + auto *ty = getClangTypeConverter().getFunctionType(params, result, trueRep); + return ty ? ty->getCanonicalTypeInternal().getTypePtr() : nullptr; } const Decl * diff --git a/lib/AST/ClangTypeConverter.cpp b/lib/AST/ClangTypeConverter.cpp index 2a08f78fb282e..9fd13f797798d 100644 --- a/lib/AST/ClangTypeConverter.cpp +++ b/lib/AST/ClangTypeConverter.cpp @@ -158,6 +158,57 @@ const clang::Type *ClangTypeConverter::getFunctionType( llvm_unreachable("invalid representation"); } +const clang::Type *ClangTypeConverter::getFunctionType( + ArrayRef params, Optional result, + SILFunctionType::Representation repr) { + + // Using the interface type is sufficient as type parameters get mapped to + // `id`, since ObjC lightweight generics use type erasure. (See also: SE-0057) + auto resultClangTy = result.hasValue() + ? convert(result.getValue().getInterfaceType()) + : ClangASTContext.VoidTy; + + if (resultClangTy.isNull()) + return nullptr; + + SmallVector extParamInfos; + SmallVector paramsClangTy; + bool someParamIsConsumed = false; + for (auto &p : params) { + auto pc = convert(p.getInterfaceType()); + if (pc.isNull()) + return nullptr; + clang::FunctionProtoType::ExtParameterInfo extParamInfo; + if (p.isConsumed()) { + someParamIsConsumed = true; + extParamInfo = extParamInfo.withIsConsumed(true); + } + extParamInfos.push_back(extParamInfo); + paramsClangTy.push_back(pc); + } + + clang::FunctionProtoType::ExtProtoInfo info(clang::CallingConv::CC_C); + if (someParamIsConsumed) + info.ExtParameterInfos = extParamInfos.begin(); + auto fn = ClangASTContext.getFunctionType(resultClangTy, paramsClangTy, info); + if (fn.isNull()) + return nullptr; + + switch (repr) { + case SILFunctionType::Representation::CFunctionPointer: + return ClangASTContext.getPointerType(fn).getTypePtr(); + case SILFunctionType::Representation::Block: + return ClangASTContext.getBlockPointerType(fn).getTypePtr(); + case SILFunctionType::Representation::Thick: + case SILFunctionType::Representation::Thin: + case SILFunctionType::Representation::Method: + case SILFunctionType::Representation::ObjCMethod: + case SILFunctionType::Representation::WitnessMethod: + case SILFunctionType::Representation::Closure: + llvm_unreachable("Expected a C-compatible representation."); + } +} + clang::QualType ClangTypeConverter::convertMemberType(NominalTypeDecl *DC, StringRef memberName) { auto memberTypeDecl = cast( diff --git a/lib/AST/ClangTypeConverter.h b/lib/AST/ClangTypeConverter.h index 450b9e30cf19a..e41a824163312 100644 --- a/lib/AST/ClangTypeConverter.h +++ b/lib/AST/ClangTypeConverter.h @@ -74,6 +74,11 @@ class ClangTypeConverter : ArrayRef params, Type resultTy, AnyFunctionType::Representation repr); + /// Compute the C function type for a SIL function type. + const clang::Type *getFunctionType( + ArrayRef params, Optional result, + SILFunctionType::Representation repr); + /// Check whether the given Clang declaration is an export of a Swift /// declaration introduced by this converter, and if so, return the original /// Swift declaration. diff --git a/lib/IRGen/GenClangType.cpp b/lib/IRGen/GenClangType.cpp index bc788fab6904a..8bc35dd99c134 100644 --- a/lib/IRGen/GenClangType.cpp +++ b/lib/IRGen/GenClangType.cpp @@ -132,10 +132,10 @@ namespace { /// ABI. class GenClangType : public CanTypeVisitor { IRGenModule &IGM; - ClangTypeConverter &Converter; + irgen::ClangTypeConverter &Converter; public: - GenClangType(IRGenModule &IGM, ClangTypeConverter &converter) + GenClangType(IRGenModule &IGM, irgen::ClangTypeConverter &converter) : IGM(IGM), Converter(converter) {} const clang::ASTContext &getClangASTContext() const { @@ -264,8 +264,8 @@ static clang::CanQualType getClangBuiltinTypeFromTypedef( } clang::CanQualType -ClangTypeConverter::reverseBuiltinTypeMapping(IRGenModule &IGM, - CanStructType type) { +irgen::ClangTypeConverter::reverseBuiltinTypeMapping(IRGenModule &IGM, + CanStructType type) { // Handle builtin types by adding entries to the cache that reverse // the mapping done by the importer. We could try to look at the // members of the struct instead, but even if that's ABI-equivalent @@ -748,7 +748,7 @@ clang::CanQualType GenClangType::visitType(CanType type) { llvm_unreachable("Unexpected type in Clang type generation."); } -clang::CanQualType ClangTypeConverter::convert(IRGenModule &IGM, CanType type) { +clang::CanQualType irgen::ClangTypeConverter::convert(IRGenModule &IGM, CanType type) { // Look in the cache. auto it = Cache.find(type); if (it != Cache.end()) { From 1807412e85f5e9fc274e254ad029ebb199f8a3fc Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 18 Aug 2020 14:44:13 -0700 Subject: [PATCH 03/10] [Serialization] Allow different Clang types in deserialization. We could've stored a function pointer or a block pointer or a function reference. --- lib/Serialization/Deserialization.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index ed98ea9976f26..724aef5da6b76 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -5413,16 +5413,12 @@ class TypeDeserializer { if (!diffKind.hasValue()) MF.fatal(); - const clang::FunctionType *clangFunctionType = nullptr; + const clang::Type *clangFunctionType = nullptr; if (clangFunctionTypeID) { auto clangType = MF.getClangType(clangFunctionTypeID); if (!clangType) return clangType.takeError(); - // FIXME: allow block pointers here. - clangFunctionType = - dyn_cast_or_null(clangType.get()); - if (!clangFunctionType) - MF.fatal(); + clangFunctionType = clangType.get(); } auto extInfo = From eaac23fdd4dbb2f35c160dabf89ea54557701950 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 18 Aug 2020 15:14:51 -0700 Subject: [PATCH 04/10] [NFC] Remove ASTExtInfo::assertIsFunctionType in favor of checkInvariants. Invariants should be checked only when calling build(), not when the builder itself is created. --- include/swift/AST/ExtInfo.h | 10 +--------- lib/AST/ExtInfo.cpp | 35 +++++++++++++++++++---------------- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/include/swift/AST/ExtInfo.h b/include/swift/AST/ExtInfo.h index 51592181aabf2..02c78efccf68f 100644 --- a/include/swift/AST/ExtInfo.h +++ b/include/swift/AST/ExtInfo.h @@ -194,16 +194,8 @@ class ASTExtInfoBuilder { using Representation = FunctionTypeRepresentation; - static void assertIsFunctionType(const clang::Type *); - ASTExtInfoBuilder(unsigned bits, ClangTypeInfo clangTypeInfo) - : bits(bits), clangTypeInfo(clangTypeInfo) { - // TODO: [clang-function-type-serialization] Once we start serializing - // the Clang type, we should also assert that the pointer is non-null. - auto Rep = Representation(bits & RepresentationMask); - if ((Rep == Representation::CFunctionPointer) && clangTypeInfo.type) - assertIsFunctionType(clangTypeInfo.type); - } + : bits(bits), clangTypeInfo(clangTypeInfo) {} public: // Constructor with all defaults. diff --git a/lib/AST/ExtInfo.cpp b/lib/AST/ExtInfo.cpp index a75a3ff1d9f5e..5b779920ace0b 100644 --- a/lib/AST/ExtInfo.cpp +++ b/lib/AST/ExtInfo.cpp @@ -19,6 +19,20 @@ #include "clang/AST/Type.h" +static void assertIsFunctionType(const clang::Type *type) { +#ifndef NDEBUG + if (!(type->isFunctionPointerType() || type->isBlockPointerType() || + type->isFunctionReferenceType())) { + llvm::SmallString<256> buf; + llvm::raw_svector_ostream os(buf); + os << "Expected a Clang function type wrapped in a pointer type or " + << "a block pointer type but found:\n"; + type->dump(os); + llvm_unreachable(os.str().data()); + } +#endif +} + namespace swift { // MARK: - ClangTypeInfo @@ -53,23 +67,12 @@ void ClangTypeInfo::dump(llvm::raw_ostream &os) const { // MARK: - ASTExtInfoBuilder -void ASTExtInfoBuilder::assertIsFunctionType(const clang::Type *type) { -#ifndef NDEBUG - if (!(type->isFunctionPointerType() || type->isBlockPointerType() || - type->isFunctionReferenceType())) { - SmallString<256> buf; - llvm::raw_svector_ostream os(buf); - os << "Expected a Clang function type wrapped in a pointer type or " - << "a block pointer type but found:\n"; - type->dump(os); - llvm_unreachable(os.str().data()); - } -#endif - return; -} - void ASTExtInfoBuilder::checkInvariants() const { - // TODO: Add validation checks here while making sure things don't blow up. + // TODO: [clang-function-type-serialization] Once we start serializing + // the Clang type, we should also assert that the pointer is non-null. + auto Rep = Representation(bits & RepresentationMask); + if ((Rep == Representation::CFunctionPointer) && clangTypeInfo.type) + assertIsFunctionType(clangTypeInfo.type); } // MARK: - ASTExtInfo From 8da4d53d2c3a0b3976b14d0e0dc38d1144191fe8 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 18 Aug 2020 16:09:32 -0700 Subject: [PATCH 05/10] [NFC] Use ClangTypeInfo's implicit null state instead of an extra Optional. --- include/swift/AST/ExtInfo.h | 19 +++++-------------- include/swift/AST/Types.h | 2 +- lib/AST/ASTContext.cpp | 12 ++++++------ lib/AST/ASTPrinter.cpp | 6 +++--- 4 files changed, 15 insertions(+), 24 deletions(-) diff --git a/include/swift/AST/ExtInfo.h b/include/swift/AST/ExtInfo.h index 02c78efccf68f..6b2bc1b8bf7c5 100644 --- a/include/swift/AST/ExtInfo.h +++ b/include/swift/AST/ExtInfo.h @@ -246,10 +246,7 @@ class ASTExtInfoBuilder { DifferentiabilityKind::NonDifferentiable; } - /// Get the underlying ClangTypeInfo value if it is not the default value. - Optional getClangTypeInfo() const { - return clangTypeInfo.empty() ? Optional() : clangTypeInfo; - } + ClangTypeInfo getClangTypeInfo() const { return clangTypeInfo; } constexpr SILFunctionTypeRepresentation getSILRepresentation() const { unsigned rawRep = bits & RepresentationMask; @@ -396,9 +393,7 @@ class ASTExtInfo { constexpr bool isDifferentiable() const { return builder.isDifferentiable(); } - Optional getClangTypeInfo() const { - return builder.getClangTypeInfo(); - } + ClangTypeInfo getClangTypeInfo() const { return builder.getClangTypeInfo(); } constexpr bool hasSelfParam() const { return builder.hasSelfParam(); } @@ -558,10 +553,8 @@ class SILExtInfoBuilder { DifferentiabilityKind::NonDifferentiable; } - /// Get the underlying ClangTypeInfo value if it is not the default value. - Optional getClangTypeInfo() const { - return clangTypeInfo.empty() ? Optional() : clangTypeInfo; - } + /// Get the underlying ClangTypeInfo value. + ClangTypeInfo getClangTypeInfo() const { return clangTypeInfo; } constexpr bool hasSelfParam() const { switch (getRepresentation()) { @@ -689,9 +682,7 @@ class SILExtInfo { constexpr bool isDifferentiable() const { return builder.isDifferentiable(); } - Optional getClangTypeInfo() const { - return builder.getClangTypeInfo(); - } + ClangTypeInfo getClangTypeInfo() const { return builder.getClangTypeInfo(); } constexpr bool hasSelfParam() const { return builder.hasSelfParam(); } diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 1dd1aed9bd772..863cce2503988 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -2872,7 +2872,7 @@ class AnyFunctionType : public TypeBase { unsigned NumParams, ExtInfo Info) : TypeBase(Kind, CanTypeContext, properties), Output(Output) { Bits.AnyFunctionType.ExtInfoBits = Info.getBits(); - Bits.AnyFunctionType.HasClangTypeInfo = Info.getClangTypeInfo().hasValue(); + Bits.AnyFunctionType.HasClangTypeInfo = !Info.getClangTypeInfo().empty(); Bits.AnyFunctionType.NumParams = NumParams; assert(Bits.AnyFunctionType.NumParams == NumParams && "Params dropped!"); // The use of both assert() and static_assert() is intentional. diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index b8a0f69ccd747..ce4f9c980bf6f 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -3131,16 +3131,16 @@ FunctionType *FunctionType::get(ArrayRef params, return funcTy; } - Optional clangTypeInfo = info.getClangTypeInfo(); + auto clangTypeInfo = info.getClangTypeInfo(); size_t allocSize = totalSizeToAlloc( - params.size(), clangTypeInfo.hasValue() ? 1 : 0); + params.size(), clangTypeInfo.empty() ? 0 : 1); void *mem = ctx.Allocate(allocSize, alignof(FunctionType), arena); bool isCanonical = isFunctionTypeCanonical(params, result); - if (clangTypeInfo.hasValue()) { + if (!clangTypeInfo.empty()) { if (ctx.LangOpts.UseClangFunctionTypes) - isCanonical &= clangTypeInfo->type->isCanonicalUnqualified(); + isCanonical &= clangTypeInfo.getType()->isCanonicalUnqualified(); else isCanonical = false; } @@ -3162,8 +3162,8 @@ FunctionType::FunctionType(ArrayRef params, std::uninitialized_copy(params.begin(), params.end(), getTrailingObjects()); auto clangTypeInfo = info.getClangTypeInfo(); - if (clangTypeInfo.hasValue()) - *getTrailingObjects() = clangTypeInfo.getValue(); + if (!clangTypeInfo.empty()) + *getTrailingObjects() = clangTypeInfo; } void GenericFunctionType::Profile(llvm::FoldingSetNodeID &ID, diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 58a220d54c776..a2eea55434aa4 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -3629,7 +3629,7 @@ void printCType(ASTContext &Ctx, ASTPrinter &Printer, ExtInfo &info) { auto *cml = Ctx.getClangModuleLoader(); SmallString<64> buf; llvm::raw_svector_ostream os(buf); - info.getClangTypeInfo().getValue().printType(cml, os); + info.getClangTypeInfo().printType(cml, os); Printer << ", cType: " << QuotedString(os.str()); } @@ -4054,7 +4054,7 @@ class TypePrinter : public TypeVisitor { case SILFunctionType::Representation::CFunctionPointer: Printer << "c"; // [TODO: Clang-type-plumbing] Remove the second check. - if (printNameOnly || !info.getClangTypeInfo().hasValue()) + if (printNameOnly || info.getClangTypeInfo().empty()) break; printCType(Ctx, Printer, info); break; @@ -4120,7 +4120,7 @@ class TypePrinter : public TypeVisitor { case SILFunctionType::Representation::CFunctionPointer: Printer << "c"; // [TODO: Clang-type-plumbing] Remove the second check. - if (printNameOnly || !info.getClangTypeInfo().hasValue()) + if (printNameOnly || info.getClangTypeInfo().empty()) break; printCType(Ctx, Printer, info); break; From eead4ae8f05a91e2a087d027e341712d500f263b Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Tue, 18 Aug 2020 16:18:38 -0700 Subject: [PATCH 06/10] [NFC] Remove unused function parameter. --- include/swift/AST/ASTContext.h | 1 - lib/AST/ASTContext.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h index e3ecfbb158dfb..7697baf4d1d01 100644 --- a/include/swift/AST/ASTContext.h +++ b/include/swift/AST/ASTContext.h @@ -606,7 +606,6 @@ class ASTContext final { const clang::Type * getCanonicalClangFunctionType( ArrayRef params, Optional result, - const SILFunctionType::ExtInfo incompleteExtInfo, SILFunctionType::Representation trueRep); /// Get the Swift declaration that a Clang declaration was exported from, diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index ce4f9c980bf6f..ca9d3ed0f34e8 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -4477,7 +4477,6 @@ const clang::Type * ASTContext::getCanonicalClangFunctionType( ArrayRef params, Optional result, - SILFunctionType::ExtInfo incompleteExtInfo, SILFunctionType::Representation trueRep) { auto *ty = getClangTypeConverter().getFunctionType(params, result, trueRep); return ty ? ty->getCanonicalTypeInternal().getTypePtr() : nullptr; From eeec16f14322e96577e21a9e0d2b554fb98dd313 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Wed, 19 Aug 2020 18:06:00 -0700 Subject: [PATCH 07/10] [NFC] Remove redundant ExtInfo parameter for getBridgedFunctionType. At all call-sites, the extInfo passed as the third argument is computed directly from the second argument, so we compute it directly in getBridgedFunctionType. --- include/swift/SIL/TypeLowering.h | 1 - lib/SIL/IR/SILFunctionType.cpp | 13 ++++--------- lib/SIL/IR/TypeLowering.cpp | 2 +- lib/SILGen/SILGenApply.cpp | 1 - lib/SILGen/SILGenBridging.cpp | 3 +-- 5 files changed, 6 insertions(+), 14 deletions(-) diff --git a/include/swift/SIL/TypeLowering.h b/include/swift/SIL/TypeLowering.h index aba919ee0090c..344087f0a1aaf 100644 --- a/include/swift/SIL/TypeLowering.h +++ b/include/swift/SIL/TypeLowering.h @@ -992,7 +992,6 @@ class TypeConverter { /// Given a function type, yield its bridged formal type. CanAnyFunctionType getBridgedFunctionType(AbstractionPattern fnPattern, CanAnyFunctionType fnType, - AnyFunctionType::ExtInfo extInfo, Bridgeability bridging); /// Given a referenced value and the substituted formal type of a diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 2d3e10054313d..794706f5c15b2 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -3984,7 +3984,6 @@ SILFunctionType::substituteOpaqueArchetypes(TypeConverter &TC, CanAnyFunctionType TypeConverter::getBridgedFunctionType(AbstractionPattern pattern, CanAnyFunctionType t, - AnyFunctionType::ExtInfo extInfo, Bridgeability bridging) { // Pull out the generic signature. CanGenericSignature genericSig = t.getOptGenericSignature(); @@ -3996,12 +3995,8 @@ TypeConverter::getBridgedFunctionType(AbstractionPattern pattern, case SILFunctionTypeRepresentation::Closure: case SILFunctionTypeRepresentation::WitnessMethod: { // No bridging needed for native functions. - if (t->getExtInfo().isEqualTo(extInfo, useClangTypes(t))) - return t; - return CanAnyFunctionType::get(genericSig, t.getParams(), t.getResult(), - extInfo); + return t; } - case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::Block: case SILFunctionTypeRepresentation::ObjCMethod: { @@ -4016,7 +4011,7 @@ TypeConverter::getBridgedFunctionType(AbstractionPattern pattern, suppressOptional); return CanAnyFunctionType::get(genericSig, llvm::makeArrayRef(params), - result, extInfo); + result, t->getExtInfo()); } } llvm_unreachable("bad calling convention"); @@ -4098,7 +4093,6 @@ TypeConverter::getLoweredFormalTypes(SILDeclRef constant, auto bridging = Bridgeability::Full; unsigned numParameterLists = constant.getParameterListCount(); - auto extInfo = fnType->getExtInfo(); // Form an abstraction pattern for bridging purposes. AbstractionPattern bridgingFnPattern = @@ -4108,12 +4102,13 @@ TypeConverter::getLoweredFormalTypes(SILDeclRef constant, // Fast path: no uncurrying required. if (numParameterLists == 1) { auto bridgedFnType = - getBridgedFunctionType(bridgingFnPattern, fnType, extInfo, bridging); + getBridgedFunctionType(bridgingFnPattern, fnType, bridging); bridgingFnPattern.rewriteType(bridgingFnPattern.getGenericSignature(), bridgedFnType); return { bridgingFnPattern, bridgedFnType }; } + auto extInfo = fnType->getExtInfo(); SILFunctionTypeRepresentation rep = extInfo.getSILRepresentation(); assert(rep != SILFunctionType::Representation::Block && "objc blocks cannot be curried"); diff --git a/lib/SIL/IR/TypeLowering.cpp b/lib/SIL/IR/TypeLowering.cpp index e1d4417e42dd6..45a725074cb8d 100644 --- a/lib/SIL/IR/TypeLowering.cpp +++ b/lib/SIL/IR/TypeLowering.cpp @@ -1964,7 +1964,7 @@ TypeConverter::computeLoweredRValueType(TypeExpansionContext forExpansion, // Bridge the parameters and result of the function type. auto bridgedFnType = - TC.getBridgedFunctionType(origType, substFnType, extInfo, bridging); + TC.getBridgedFunctionType(origType, substFnType, bridging); substFnType = bridgedFnType; // Also rewrite the type of the abstraction pattern. diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index bffecc2c2c187..22d3136ca776c 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -76,7 +76,6 @@ getIndirectApplyAbstractionPattern(SILGenFunction &SGF, // bridged to a foreign type. auto bridgedType = SGF.SGM.Types.getBridgedFunctionType(pattern, fnType, - fnType->getExtInfo(), Bridgeability::Full); pattern.rewriteType(CanGenericSignature(), bridgedType); return pattern; diff --git a/lib/SILGen/SILGenBridging.cpp b/lib/SILGen/SILGenBridging.cpp index 7eedc3b1975fa..0c1bb7d417a89 100644 --- a/lib/SILGen/SILGenBridging.cpp +++ b/lib/SILGen/SILGenBridging.cpp @@ -350,8 +350,7 @@ getParameterTypes(AnyFunctionType::CanParamArrayRef params) { static CanAnyFunctionType getBridgedBlockType(SILGenModule &SGM, CanAnyFunctionType blockType) { return SGM.Types.getBridgedFunctionType(AbstractionPattern(blockType), - blockType, blockType->getExtInfo(), - Bridgeability::Full); + blockType, Bridgeability::Full); } static void buildFuncToBlockInvokeBody(SILGenFunction &SGF, From fdbcd1236fd6d94239eb37b07cb729c4eae466aa Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Thu, 20 Aug 2020 17:11:48 -0700 Subject: [PATCH 08/10] [NFC] Bridge based on SILFunctionLanguage instead of Representation. --- lib/SIL/IR/SILFunctionType.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 794706f5c15b2..29a40a911d107 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -3988,18 +3988,13 @@ TypeConverter::getBridgedFunctionType(AbstractionPattern pattern, // Pull out the generic signature. CanGenericSignature genericSig = t.getOptGenericSignature(); - switch (auto rep = t->getExtInfo().getSILRepresentation()) { - case SILFunctionTypeRepresentation::Thick: - case SILFunctionTypeRepresentation::Thin: - case SILFunctionTypeRepresentation::Method: - case SILFunctionTypeRepresentation::Closure: - case SILFunctionTypeRepresentation::WitnessMethod: { + auto rep = t->getExtInfo().getSILRepresentation(); + switch (getSILFunctionLanguage(rep)) { + case SILFunctionLanguage::Swift: { // No bridging needed for native functions. return t; } - case SILFunctionTypeRepresentation::CFunctionPointer: - case SILFunctionTypeRepresentation::Block: - case SILFunctionTypeRepresentation::ObjCMethod: { + case SILFunctionLanguage::C: { SmallVector params; getBridgedParams(rep, pattern, t->getParams(), params, bridging); From f86aad9b294819a84aa1493330e07b0675ac90e6 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Thu, 20 Aug 2020 18:00:27 -0700 Subject: [PATCH 09/10] [NFC] Extract computation of SILExtInfoBuilder bits into new method. --- include/swift/AST/ExtInfo.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/include/swift/AST/ExtInfo.h b/include/swift/AST/ExtInfo.h index 6b2bc1b8bf7c5..0850870f6ce45 100644 --- a/include/swift/AST/ExtInfo.h +++ b/include/swift/AST/ExtInfo.h @@ -505,6 +505,15 @@ class SILExtInfoBuilder { SILExtInfoBuilder(unsigned bits, ClangTypeInfo clangTypeInfo) : bits(bits), clangTypeInfo(clangTypeInfo) {} + static constexpr unsigned makeBits(Representation rep, bool isPseudogeneric, + bool isNoEscape, bool isAsync, + DifferentiabilityKind diffKind) { + return ((unsigned)rep) | (isPseudogeneric ? PseudogenericMask : 0) | + (isNoEscape ? NoEscapeMask : 0) | (isAsync ? AsyncMask : 0) | + (((unsigned)diffKind << DifferentiabilityMaskOffset) & + DifferentiabilityMask); + } + public: // Constructor with all defaults. SILExtInfoBuilder() : bits(0), clangTypeInfo(ClangTypeInfo(nullptr)) {} @@ -513,12 +522,9 @@ class SILExtInfoBuilder { SILExtInfoBuilder(Representation rep, bool isPseudogeneric, bool isNoEscape, bool isAsync, DifferentiabilityKind diffKind, const clang::Type *type) - : SILExtInfoBuilder( - ((unsigned)rep) | (isPseudogeneric ? PseudogenericMask : 0) | - (isNoEscape ? NoEscapeMask : 0) | (isAsync ? AsyncMask : 0) | - (((unsigned)diffKind << DifferentiabilityMaskOffset) & - DifferentiabilityMask), - ClangTypeInfo(type)) {} + : SILExtInfoBuilder(makeBits(rep, isPseudogeneric, isNoEscape, isAsync, + diffKind), + ClangTypeInfo(type)) {} void checkInvariants() const; From c4ad840ad3dbc40c885af117105a3a92326df149 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Thu, 20 Aug 2020 17:40:41 -0700 Subject: [PATCH 10/10] [NFC] Reuse SILExtInfoBuilder's main constructor in default constructor. --- include/swift/AST/ExtInfo.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/swift/AST/ExtInfo.h b/include/swift/AST/ExtInfo.h index 0850870f6ce45..55ea27bc47dc8 100644 --- a/include/swift/AST/ExtInfo.h +++ b/include/swift/AST/ExtInfo.h @@ -516,7 +516,7 @@ class SILExtInfoBuilder { public: // Constructor with all defaults. - SILExtInfoBuilder() : bits(0), clangTypeInfo(ClangTypeInfo(nullptr)) {} + SILExtInfoBuilder() : SILExtInfoBuilder(0, ClangTypeInfo(nullptr)) {} // Constructor for polymorphic type. SILExtInfoBuilder(Representation rep, bool isPseudogeneric, bool isNoEscape, @@ -526,6 +526,12 @@ class SILExtInfoBuilder { diffKind), ClangTypeInfo(type)) {} + SILExtInfoBuilder(ASTExtInfoBuilder info, bool isPseudogeneric) + : SILExtInfoBuilder(makeBits(info.getSILRepresentation(), isPseudogeneric, + info.isNoEscape(), info.isAsync(), + info.getDifferentiabilityKind()), + info.getClangTypeInfo()) {} + void checkInvariants() const; /// Check if \c this is well-formed and create an ExtInfo.