diff --git a/include/swift/AST/ExtInfo.h b/include/swift/AST/ExtInfo.h index 8537968945fe3..5adf3a0b2489f 100644 --- a/include/swift/AST/ExtInfo.h +++ b/include/swift/AST/ExtInfo.h @@ -172,6 +172,13 @@ enum class SILFunctionTypeRepresentation : uint8_t { /// constructor). Except for /// handling the "this" argument, has the same behavior as "CFunctionPointer". CXXMethod, + + /// A KeyPath accessor function, which is thin and also uses the variadic length + /// generic components serialization in trailing buffer. + KeyPathAccessorGetter, + KeyPathAccessorSetter, + KeyPathAccessorEquals, + KeyPathAccessorHash, }; /// Returns true if the function with this convention doesn't carry a context. @@ -202,6 +209,10 @@ isThinRepresentation(SILFunctionTypeRepresentation rep) { case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::Closure: case SILFunctionTypeRepresentation::CXXMethod: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return true; } llvm_unreachable("Unhandled SILFunctionTypeRepresentation in switch."); @@ -214,6 +225,30 @@ isThickRepresentation(Repr repr) { return !isThinRepresentation(repr); } +/// Returns true if the function with this convention doesn't carry a context. +constexpr bool +isKeyPathAccessorRepresentation(SILFunctionTypeRepresentation rep) { + switch (rep) { + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: + return true; + case SILFunctionTypeRepresentation::Thick: + case SILFunctionTypeRepresentation::Block: + case SILFunctionTypeRepresentation::Thin: + case SILFunctionTypeRepresentation::Method: + case SILFunctionTypeRepresentation::ObjCMethod: + case SILFunctionTypeRepresentation::WitnessMethod: + case SILFunctionTypeRepresentation::CFunctionPointer: + case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::CXXMethod: + return false; + } + llvm_unreachable("Unhandled SILFunctionTypeRepresentation in switch."); +} + + constexpr SILFunctionTypeRepresentation convertRepresentation(FunctionTypeRepresentation rep) { switch (rep) { @@ -225,6 +260,7 @@ convertRepresentation(FunctionTypeRepresentation rep) { return SILFunctionTypeRepresentation::Thin; case FunctionTypeRepresentation::CFunctionPointer: return SILFunctionTypeRepresentation::CFunctionPointer; + return SILFunctionTypeRepresentation::Thin; } llvm_unreachable("Unhandled FunctionTypeRepresentation!"); } @@ -245,6 +281,10 @@ convertRepresentation(SILFunctionTypeRepresentation rep) { case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::WitnessMethod: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return None; } llvm_unreachable("Unhandled SILFunctionTypeRepresentation!"); @@ -264,6 +304,10 @@ constexpr bool canBeCalledIndirectly(SILFunctionTypeRepresentation rep) { case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return true; } @@ -285,6 +329,10 @@ template constexpr bool shouldStoreClangType(Repr repr) { case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return false; } llvm_unreachable("Unhandled SILFunctionTypeRepresentation."); @@ -395,6 +443,10 @@ class ASTExtInfoBuilder { case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return false; case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::Method: @@ -633,6 +685,10 @@ SILFunctionLanguage getSILFunctionLanguage(SILFunctionTypeRepresentation rep) { case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return SILFunctionLanguage::Swift; } @@ -651,17 +707,17 @@ class SILExtInfoBuilder { // and NumMaskBits must be updated, and they must match. // |representation|pseudogeneric| noescape | concurrent | async |differentiability| - // | 0 .. 3 | 4 | 5 | 6 | 7 | 8 .. 10 | + // | 0 .. 4 | 5 | 6 | 7 | 8 | 9 .. 11 | // enum : unsigned { - RepresentationMask = 0xF << 0, - PseudogenericMask = 1 << 4, - NoEscapeMask = 1 << 5, - SendableMask = 1 << 6, - AsyncMask = 1 << 7, - DifferentiabilityMaskOffset = 8, + RepresentationMask = 0x1F << 0, + PseudogenericMask = 1 << 5, + NoEscapeMask = 1 << 6, + SendableMask = 1 << 7, + AsyncMask = 1 << 8, + DifferentiabilityMaskOffset = 9, DifferentiabilityMask = 0x7 << DifferentiabilityMaskOffset, - NumMaskBits = 11 + NumMaskBits = 12 }; unsigned bits; // Naturally sized for speed. @@ -755,6 +811,10 @@ class SILExtInfoBuilder { case Representation::Thin: case Representation::CFunctionPointer: case Representation::Closure: + case Representation::KeyPathAccessorGetter: + case Representation::KeyPathAccessorSetter: + case Representation::KeyPathAccessorEquals: + case Representation::KeyPathAccessorHash: return false; case Representation::ObjCMethod: case Representation::Method: @@ -778,6 +838,10 @@ class SILExtInfoBuilder { case Representation::WitnessMethod: case Representation::Closure: case SILFunctionTypeRepresentation::CXXMethod: + case Representation::KeyPathAccessorGetter: + case Representation::KeyPathAccessorSetter: + case Representation::KeyPathAccessorEquals: + case Representation::KeyPathAccessorHash: return false; } llvm_unreachable("Unhandled Representation in switch."); diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 09f0b12a1bc47..dccaa01efe1b0 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -340,7 +340,7 @@ class alignas(1 << TypeAlignInBits) TypeBase protected: enum { NumAFTExtInfoBits = 11 }; - enum { NumSILExtInfoBits = 11 }; + enum { NumSILExtInfoBits = 12 }; union { uint64_t OpaqueBits; SWIFT_INLINE_BITFIELD_BASE(TypeBase, bitmax(NumTypeKindBits,8) + diff --git a/include/swift/SIL/ApplySite.h b/include/swift/SIL/ApplySite.h index 9c2a3e0cd1d78..ffcc76d95dff6 100644 --- a/include/swift/SIL/ApplySite.h +++ b/include/swift/SIL/ApplySite.h @@ -21,6 +21,7 @@ #ifndef SWIFT_SIL_APPLYSITE_H #define SWIFT_SIL_APPLYSITE_H +#include "swift/AST/ExtInfo.h" #include "swift/Basic/STLExtras.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBasicBlock.h" @@ -253,6 +254,10 @@ class ApplySite { case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::WitnessMethod: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return true; case SILFunctionTypeRepresentation::Block: case SILFunctionTypeRepresentation::Thick: diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 40bd08776732d..71b34ac490029 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -136,6 +136,10 @@ getSILFunctionTypeRepresentationString(SILFunctionType::Representation value) { case SILFunctionType::Representation::ObjCMethod: return "objc_method"; case SILFunctionType::Representation::WitnessMethod: return "witness_method"; case SILFunctionType::Representation::Closure: return "closure"; + case SILFunctionType::Representation::KeyPathAccessorGetter: return "keypath_accessor_getter"; + case SILFunctionType::Representation::KeyPathAccessorSetter: return "keypath_accessor_setter"; + case SILFunctionType::Representation::KeyPathAccessorEquals: return "keypath_accessor_equals"; + case SILFunctionType::Representation::KeyPathAccessorHash: return "keypath_accessor_hash"; } llvm_unreachable("Unhandled SILFunctionTypeRepresentation in switch."); diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp index aa1a61985d7a6..3f50a2fe83557 100644 --- a/lib/AST/ASTMangler.cpp +++ b/lib/AST/ASTMangler.cpp @@ -1872,6 +1872,12 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn, case SILFunctionTypeRepresentation::WitnessMethod: OpArgs.push_back('W'); break; + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: + OpArgs.push_back('P'); + break; } // Coroutine kind. This is mangled in all pointer auth modes. diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 57f9651eb571b..1503ba48424a2 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -5785,6 +5785,18 @@ class TypePrinter : public TypeVisitor { case SILFunctionType::Representation::Closure: Printer << "closure"; break; + case SILFunctionType::Representation::KeyPathAccessorGetter: + Printer << "keypath_accessor_getter"; + break; + case SILFunctionType::Representation::KeyPathAccessorSetter: + Printer << "keypath_accessor_setter"; + break; + case SILFunctionType::Representation::KeyPathAccessorEquals: + Printer << "keypath_accessor_equals"; + break; + case SILFunctionType::Representation::KeyPathAccessorHash: + Printer << "keypath_accessor_hash"; + break; } Printer << ")"; Printer.printStructurePost(PrintStructureKind::BuiltinAttribute); @@ -5869,6 +5881,18 @@ class TypePrinter : public TypeVisitor { case SILFunctionType::Representation::Closure: Printer << "closure"; break; + case SILFunctionType::Representation::KeyPathAccessorGetter: + Printer << "keypath_accessor_getter"; + break; + case SILFunctionType::Representation::KeyPathAccessorSetter: + Printer << "keypath_accessor_setter"; + break; + case SILFunctionType::Representation::KeyPathAccessorEquals: + Printer << "keypath_accessor_equals"; + break; + case SILFunctionType::Representation::KeyPathAccessorHash: + Printer << "keypath_accessor_hash"; + break; } Printer << ")"; Printer.printStructurePost(PrintStructureKind::BuiltinAttribute); diff --git a/lib/AST/ClangTypeConverter.cpp b/lib/AST/ClangTypeConverter.cpp index 98f6106b0b676..6bb2adcd69a70 100644 --- a/lib/AST/ClangTypeConverter.cpp +++ b/lib/AST/ClangTypeConverter.cpp @@ -223,6 +223,10 @@ const clang::Type *ClangTypeConverter::getFunctionType( case SILFunctionType::Representation::ObjCMethod: case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: llvm_unreachable("Expected a C-compatible representation."); } llvm_unreachable("unhandled representation!"); diff --git a/lib/FrontendTool/TBD.cpp b/lib/FrontendTool/TBD.cpp index 1619f2c87c03e..938eba8b6d0af 100644 --- a/lib/FrontendTool/TBD.cpp +++ b/lib/FrontendTool/TBD.cpp @@ -66,13 +66,22 @@ bool swift::writeTBD(ModuleDecl *M, StringRef OutputFilename, /// should be ignored (instead of potentially producing a diagnostic.) static bool isSymbolIgnored(const StringRef& name, const llvm::Module &IRModule) { - if (llvm::Triple(IRModule.getTargetTriple()).isOSWindows()) { + llvm::Triple triple(IRModule.getTargetTriple()); + if (triple.isOSWindows()) { // (SR-15938) Error when referencing #dsohandle in a Swift test on Windows // On Windows, ignore the lack of __ImageBase in the TBD file. if (name == "__ImageBase") { return true; } } + if (triple.isWasm()) { + // `__main_void`, which is called by `_start` in crt1.o, is artificially + // aliased in IR module when `main` doesn't take any params. + // This alias will be hidden after https://reviews.llvm.org/D75277 + if (name == "__main_void") { + return true; + } + } return false; } diff --git a/lib/IRGen/CallEmission.h b/lib/IRGen/CallEmission.h index a0467ae40fc20..11ccedd653f96 100644 --- a/lib/IRGen/CallEmission.h +++ b/lib/IRGen/CallEmission.h @@ -17,6 +17,7 @@ #ifndef SWIFT_IRGEN_CALLEMISSION_H #define SWIFT_IRGEN_CALLEMISSION_H +#include "Address.h" #include "Temporary.h" #include "Callee.h" @@ -49,6 +50,8 @@ class CallEmission { /// Temporaries required by the call. TemporarySet Temporaries; + SmallVector RawTempraries; + /// The function we're going to call. Callee CurCallee; diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index e42cd88357966..903c895116ba5 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -16,9 +16,12 @@ // //===----------------------------------------------------------------------===// +#include "GenKeyPath.h" +#include "Temporary.h" #include "swift/ABI/MetadataValues.h" #include "swift/AST/ASTContext.h" #include "swift/AST/GenericEnvironment.h" +#include "swift/Basic/Range.h" #include "swift/Runtime/Config.h" #include "swift/IRGen/Linking.h" #include "swift/SIL/SILModule.h" @@ -28,8 +31,10 @@ #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/CodeGenABITypes.h" #include "clang/CodeGen/ModuleBuilder.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/GlobalPtrAuthInfo.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorHandling.h" #include "CallEmission.h" #include "EntryPointArgumentEmission.h" @@ -307,6 +312,10 @@ llvm::CallingConv::ID irgen::expandCallingConv(IRGenModule &IGM, case SILFunctionTypeRepresentation::Closure: case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Thick: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: if (isAsync) return IGM.SwiftAsyncCC; return getFreestandingConvention(IGM); @@ -466,6 +475,7 @@ namespace { llvm::Type *expandDirectResult(); void expandIndirectResults(); void expandParameters(); + void expandKeyPathAccessorParameters(); void expandExternalSignatureTypes(); void expandCoroutineResult(bool forContinuation); @@ -1342,6 +1352,10 @@ void SignatureExpansion::expandExternalSignatureTypes() { case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: llvm_unreachable("not a C representation"); } @@ -1590,6 +1604,60 @@ bool irgen::hasSelfContextParameter(CanSILFunctionType fnType) { return false; } +void SignatureExpansion::expandKeyPathAccessorParameters() { + auto params = FnType->getParameters(); + unsigned numArgsToExpand; + SmallVector tailParams; + + switch (FnType->getRepresentation()) { + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + // from: (base: CurValue, indices: (X, Y, ...)) + // to: (base: CurValue, argument: UnsafeRawPointer, size: Int) + numArgsToExpand = 1; + tailParams.push_back(IGM.Int8PtrTy); + tailParams.push_back(IGM.SizeTy); + break; + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + // from: (value: NewValue, base: CurValue, indices: (X, Y, ...)) + // to: (value: NewValue, base: CurValue, argument: UnsafeRawPointer, size: Int) + numArgsToExpand = 2; + tailParams.push_back(IGM.Int8PtrTy); + tailParams.push_back(IGM.SizeTy); + break; + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + // from: (lhsIndices: (X, Y, ...), rhsIndices: (X, Y, ...)) + // to: (lhsArguments: UnsafeRawPointer, rhsArguments: UnsafeRawPointer, size: Int) + numArgsToExpand = 0; + tailParams.push_back(IGM.Int8PtrTy); + tailParams.push_back(IGM.Int8PtrTy); + tailParams.push_back(IGM.SizeTy); + break; + case SILFunctionTypeRepresentation::KeyPathAccessorHash: + // from: (indices: (X, Y, ...)) + // to: (instanceArguments: UnsafeRawPointer, size: Int) + numArgsToExpand = 0; + tailParams.push_back(IGM.Int8PtrTy); + tailParams.push_back(IGM.SizeTy); + break; + case SILFunctionTypeRepresentation::Thick: + case SILFunctionTypeRepresentation::Block: + case SILFunctionTypeRepresentation::Thin: + case SILFunctionTypeRepresentation::Method: + case SILFunctionTypeRepresentation::ObjCMethod: + case SILFunctionTypeRepresentation::WitnessMethod: + case SILFunctionTypeRepresentation::CFunctionPointer: + case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::CXXMethod: + llvm_unreachable("non keypath accessor convention"); + } + for (unsigned i = 0; i < numArgsToExpand; i++) { + expand(params[i]); + } + for (auto tailParam : tailParams) { + ParamIRTypes.push_back(tailParam); + } +} + /// Expand the abstract parameters of a SIL function type into the physical /// parameters of an LLVM function type (results have already been expanded). void SignatureExpansion::expandParameters() { @@ -1661,6 +1729,12 @@ void SignatureExpansion::expandParameters() { case SILFunctionType::Representation::Closure: return FnType->hasErrorResult(); + // KeyPath accessor always has no context. + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: + return false; case SILFunctionType::Representation::Thick: return true; } @@ -1703,7 +1777,18 @@ void SignatureExpansion::expandFunctionType() { return; } expandResult(); - expandParameters(); + + switch (FnType->getRepresentation()) { + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: + expandKeyPathAccessorParameters(); + break; + default: + expandParameters(); + break; + } return; } case SILFunctionLanguage::C: @@ -1826,6 +1911,10 @@ void SignatureExpansion::expandAsyncEntryType() { case SILFunctionType::Representation::Thin: case SILFunctionType::Representation::Closure: case SILFunctionType::Representation::CXXMethod: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: return false; case SILFunctionType::Representation::Thick: @@ -2250,6 +2339,60 @@ class SyncCallEmission final : public CallEmission { isOutlined); break; + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: { + // CurCallee.getFunctionPointer().getRawPointer()->dump(); + // IGF.Builder.GetInsertBlock()->getParent()->dump(); + // origCalleeType->getInvocationGenericSignature()->dump(); + + auto params = origCalleeType->getParameters(); + + switch (getCallee().getRepresentation()) { + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: { + // add base value + addNativeArgument(IGF, original, origCalleeType, params[0], adjusted, + isOutlined); + params = params.drop_back(); + break; + } + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: { + // add base value + addNativeArgument(IGF, original, origCalleeType, params[0], adjusted, + isOutlined); + // add new value + addNativeArgument(IGF, original, origCalleeType, params[1], adjusted, + isOutlined); + params = params.drop_back(2); + break; + } + default: + llvm_unreachable("unexpected representation"); + } + + Optional dynamicArgsBuf; + SmallVector indiceTypes; + for (auto i : indices(params)) { + auto ty = getParameterType(i); + indiceTypes.push_back(ty); + } + auto sig = origCalleeType->getInvocationGenericSignature(); + auto args = emitKeyPathInstantiationArgument( + IGF, getCallee().getSubstitutions(), sig, indiceTypes, original, + dynamicArgsBuf, [&](GenericRequirement reqt) -> llvm::Value * { + return original.claimNext(); + }); + if (dynamicArgsBuf) { + RawTempraries.push_back(*dynamicArgsBuf); + } + + // add arg buffer + adjusted.add(args.first); + // add arg buffer size + adjusted.add(args.second); + break; + } case SILFunctionTypeRepresentation::WitnessMethod: assert(witnessMetadata); assert(witnessMetadata->SelfMetadata->getType() == @@ -2504,6 +2647,10 @@ class AsyncCallEmission final : public CallEmission { case SILFunctionTypeRepresentation::Block: case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::CXXMethod: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: assert(false && "Should not reach this"); break; @@ -2868,9 +3015,14 @@ llvm::CallInst *CallEmission::emitCallSite() { if (!IsCoroutine) { Temporaries.destroyAll(IGF); + for (auto &stackAddr : RawTempraries) { + IGF.emitDeallocateDynamicAlloca(stackAddr); + } + // Clear the temporary set so that we can assert that there are no // temporaries later. Temporaries.clear(); + RawTempraries.clear(); } // Return. @@ -3147,6 +3299,7 @@ CallEmission::~CallEmission() { assert(LastArgWritten == 0); assert(EmittedCall); assert(Temporaries.hasBeenCleared()); + assert(RawTempraries.empty()); assert(state == State::Finished); } @@ -3185,6 +3338,10 @@ Callee::Callee(CalleeInfo &&info, const FunctionPointer &fn, case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Closure: case SILFunctionTypeRepresentation::CFunctionPointer: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: assert(!FirstData && !SecondData); break; case SILFunctionTypeRepresentation::CXXMethod: @@ -3203,6 +3360,10 @@ llvm::Value *Callee::getSwiftContext() const { case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Closure: case SILFunctionTypeRepresentation::CXXMethod: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return nullptr; case SILFunctionTypeRepresentation::WitnessMethod: diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp index 859913e9a93e5..208d8c1bd0491 100644 --- a/lib/IRGen/GenFunc.cpp +++ b/lib/IRGen/GenFunc.cpp @@ -533,6 +533,10 @@ const TypeInfo *TypeConverter::convertFunctionType(SILFunctionType *T) { case SILFunctionType::Representation::ObjCMethod: case SILFunctionType::Representation::CFunctionPointer: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: return ThinFuncTypeInfo::create(CanSILFunctionType(T), IGM.FunctionPtrTy, IGM.getPointerSize(), @@ -588,6 +592,10 @@ getFuncSignatureInfoForLowered(IRGenModule &IGM, CanSILFunctionType type) { case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::ObjCMethod: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: return ti.as(); case SILFunctionType::Representation::Thick: return ti.as(); diff --git a/lib/IRGen/GenKeyPath.cpp b/lib/IRGen/GenKeyPath.cpp index 44c816c7c350d..d1dddb89be49e 100644 --- a/lib/IRGen/GenKeyPath.cpp +++ b/lib/IRGen/GenKeyPath.cpp @@ -32,15 +32,19 @@ #include "IRGenFunction.h" #include "IRGenMangler.h" #include "IRGenModule.h" +#include "LoadableTypeInfo.h" #include "MetadataLayout.h" #include "ProtocolInfo.h" #include "StructLayout.h" #include "TypeInfo.h" +#include "GenKeyPath.h" #include "llvm/ADT/SetVector.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/Module.h" #include "llvm/IR/Function.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILLocation.h" +#include "swift/SIL/SILType.h" #include "swift/SIL/TypeLowering.h" #include "swift/ABI/KeyPath.h" #include "swift/ABI/HeapObject.h" @@ -68,9 +72,8 @@ enum KeyPathAccessor { Hash, }; -static void -bindPolymorphicArgumentsFromComponentIndices(IRGenFunction &IGF, - const KeyPathPatternComponent &component, +void +irgen::bindPolymorphicArgumentsFromComponentIndices(IRGenFunction &IGF, GenericEnvironment *genericEnv, ArrayRef requirements, llvm::Value *args, @@ -99,6 +102,73 @@ bindPolymorphicArgumentsFromComponentIndices(IRGenFunction &IGF, }); } +static llvm::Function * +getAccessorThunkIfRequired(IRGenModule &IGM, + const KeyPathPatternComponent &component, + KeyPathAccessor whichAccessor) { + SILFunction *accessor; + switch (whichAccessor) { + case Getter: + accessor = component.getComputedPropertyGetter(); + break; + case Setter: + accessor = component.getComputedPropertySetter(); + break; + case Equals: + accessor = component.getSubscriptIndexEquals(); + break; + case Hash: + accessor = component.getSubscriptIndexHash(); + break; + } + // If the accessor is locally available, we can use it as is. + // If it's only externally available, we need a local thunk to relative- + // reference. + if (!isAvailableExternally(accessor->getLinkage()) && + &IGM == IGM.IRGen.getGenModule(accessor)) { + return IGM.getAddrOfSILFunction(accessor, NotForDefinition); + } + + const char *thunkName; + switch (whichAccessor) { + case Getter: + thunkName = "keypath_get"; + break; + case Setter: + thunkName = "keypath_set"; + break; + case Equals: + thunkName = "keypath_equals"; + break; + case Hash: + thunkName = "keypath_hash"; + break; + } + + auto accessorFn = IGM.getAddrOfSILFunction(accessor, NotForDefinition); + auto accessorThunk = llvm::Function::Create(accessorFn->getFunctionType(), + llvm::GlobalValue::PrivateLinkage, thunkName, IGM.getModule()); + accessorThunk->setAttributes(IGM.constructInitialAttributes()); + accessorThunk->setCallingConv(IGM.SwiftCC); + accessorThunk->setAttributes(accessorFn->getAttributes()); + { + IRGenFunction IGF(IGM, accessorThunk); + if (IGM.DebugInfo) + IGM.DebugInfo->emitArtificialFunction(IGF, accessorThunk); + Explosion forwardedArgs = IGF.collectParameters(); + auto fnPtr = + FunctionPointer::forDirect(IGM, accessorFn, /*secondaryValue*/ nullptr, + accessor->getLoweredFunctionType()); + auto call = IGF.Builder.CreateCall(fnPtr, forwardedArgs.claimAll()); + if (call->getType()->isVoidTy()) + IGF.Builder.CreateRetVoid(); + else + IGF.Builder.CreateRet(call); + } + + return accessorThunk; +} + static llvm::Function * getAccessorForComputedComponent(IRGenModule &IGM, const KeyPathPatternComponent &component, @@ -121,6 +191,7 @@ getAccessorForComputedComponent(IRGenModule &IGM, accessor = component.getSubscriptIndexHash(); break; } + // If the accessor is not generic, and locally available, we can use it as is. // If it's only externally available, we need a local thunk to relative- // reference. @@ -226,8 +297,7 @@ getAccessorForComputedComponent(IRGenModule &IGM, componentArgsBuf = params.claimNext(); // Pass the argument pointer down to the underlying function, if it // wants it. - // Always forward extra argument to match callee and caller signature on WebAssembly - if (hasSubscriptIndices || IGM.TargetInfo.OutputObjectFormat == llvm::Triple::Wasm) { + if (hasSubscriptIndices) { forwardedArgs.add(componentArgsBuf); } break; @@ -238,7 +308,7 @@ getAccessorForComputedComponent(IRGenModule &IGM, break; } auto componentArgsBufSize = params.claimNext(); - bindPolymorphicArgumentsFromComponentIndices(IGF, component, + bindPolymorphicArgumentsFromComponentIndices(IGF, genericEnv, requirements, componentArgsBuf, componentArgsBufSize, @@ -253,10 +323,6 @@ getAccessorForComputedComponent(IRGenModule &IGM, forwardingSubs, &ignoreWitnessMetadata, forwardedArgs); - } else if (IGM.Triple.isOSBinFormatWasm()) { - // wasm: Add null swift.type pointer to match signature even when there is - // no generic environment. - forwardedArgs.add(llvm::ConstantPointerNull::get(IGM.TypeMetadataPtrTy)); } auto fnPtr = FunctionPointer::forDirect(IGM, accessorFn, /*secondaryValue*/ nullptr, @@ -388,7 +454,6 @@ getWitnessTableForComputedComponent(IRGenModule &IGM, /*vararg*/ false); auto destroyFn = llvm::Function::Create(destroyType, llvm::GlobalValue::PrivateLinkage, "keypath_destroy", IGM.getModule()); - destroyFn->setCallingConv(IGM.SwiftCC); destroy = destroyFn; destroyFn->setAttributes(IGM.constructInitialAttributes()); destroyFn->setCallingConv(IGM.SwiftCC); @@ -400,7 +465,7 @@ getWitnessTableForComputedComponent(IRGenModule &IGM, auto params = IGF.collectParameters(); auto componentArgsBuf = params.claimNext(); auto componentArgsBufSize = params.claimNext(); - bindPolymorphicArgumentsFromComponentIndices(IGF, component, + bindPolymorphicArgumentsFromComponentIndices(IGF, genericEnv, requirements, componentArgsBuf, componentArgsBufSize, @@ -442,7 +507,6 @@ getWitnessTableForComputedComponent(IRGenModule &IGM, /*vararg*/ false); auto copyFn = llvm::Function::Create(copyType, llvm::GlobalValue::PrivateLinkage, "keypath_copy", IGM.getModule()); - copyFn->setCallingConv(IGM.SwiftCC); copy = copyFn; copyFn->setAttributes(IGM.constructInitialAttributes()); copyFn->setCallingConv(IGM.SwiftCC); @@ -455,7 +519,7 @@ getWitnessTableForComputedComponent(IRGenModule &IGM, auto sourceArgsBuf = params.claimNext(); auto destArgsBuf = params.claimNext(); auto componentArgsBufSize = params.claimNext(); - bindPolymorphicArgumentsFromComponentIndices(IGF, component, + bindPolymorphicArgumentsFromComponentIndices(IGF, genericEnv, requirements, sourceArgsBuf, componentArgsBufSize, @@ -521,12 +585,8 @@ getWitnessTableForComputedComponent(IRGenModule &IGM, } } - auto equals = getAccessorForComputedComponent(IGM, component, Equals, - genericEnv, requirements, - !component.getSubscriptIndices().empty()); - auto hash = getAccessorForComputedComponent(IGM, component, Hash, - genericEnv, requirements, - !component.getSubscriptIndices().empty()); + auto equals = getAccessorThunkIfRequired(IGM, component, Equals); + auto hash = getAccessorThunkIfRequired(IGM, component, Hash); ConstantInitBuilder builder(IGM); ConstantStructBuilder fields = builder.beginStruct(); @@ -1116,14 +1176,10 @@ emitKeyPathComponent(IRGenModule &IGM, // Push the accessors, possibly thunked to marshal generic environment. fields.addCompactFunctionReference( - getAccessorForComputedComponent(IGM, component, Getter, - genericEnv, requirements, - hasSubscriptIndices)); + getAccessorThunkIfRequired(IGM, component, Getter)); if (settable) fields.addCompactFunctionReference( - getAccessorForComputedComponent(IGM, component, Setter, - genericEnv, requirements, - hasSubscriptIndices)); + getAccessorThunkIfRequired(IGM, component, Setter)); if (!isInstantiableOnce) { // If there's generic context or subscript indexes, embed as @@ -1420,3 +1476,85 @@ void IRGenModule::emitSILProperty(SILProperty *prop) { var->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); var->setAlignment(llvm::MaybeAlign(4)); } + +std::pair +irgen::emitKeyPathInstantiationArgument( + IRGenFunction &IGF, SubstitutionMap subs, const CanGenericSignature &sig, + ArrayRef indiceTypes, Explosion &indiceValues, + Optional &dynamicArgsBuf, + EmitGenericRequirementFn emitRequirement) { + auto &IGM = IGF.IGM; + + if (!subs.empty() || !indiceTypes.empty()) { + + SmallVector requirements; + enumerateGenericSignatureRequirements( + sig, [&](GenericRequirement reqt) { requirements.push_back(reqt); }); + + llvm::Value *argsBufSize; + llvm::Value *argsBufAlign; + + if (!subs.empty()) { + argsBufSize = llvm::ConstantInt::get( + IGM.SizeTy, IGM.getPointerSize().getValue() * requirements.size()); + argsBufAlign = llvm::ConstantInt::get( + IGM.SizeTy, IGM.getPointerAlignment().getMaskValue()); + } else { + argsBufSize = llvm::ConstantInt::get(IGM.SizeTy, 0); + argsBufAlign = llvm::ConstantInt::get(IGM.SizeTy, 0); + } + + SmallVector operandOffsets; + for (unsigned i : indices(indiceTypes)) { + auto ty = indiceTypes[i]; + auto &ti = IGF.getTypeInfo(ty); + auto alignMask = ti.getAlignmentMask(IGF, ty); + if (i != 0) { + auto notAlignMask = IGF.Builder.CreateNot(alignMask); + argsBufSize = IGF.Builder.CreateAdd(argsBufSize, alignMask); + argsBufSize = IGF.Builder.CreateAnd(argsBufSize, notAlignMask); + } + operandOffsets.push_back(argsBufSize); + auto size = ti.getSize(IGF, ty); + argsBufSize = IGF.Builder.CreateAdd(argsBufSize, size); + argsBufAlign = IGF.Builder.CreateOr(argsBufAlign, alignMask); + } + + dynamicArgsBuf = + IGF.emitDynamicAlloca(IGM.Int8Ty, argsBufSize, Alignment(16)); + + Address argsBuf = dynamicArgsBuf->getAddress(); + + if (!subs.empty()) { + emitInitOfGenericRequirementsBuffer(IGF, requirements, argsBuf, + emitRequirement); + } + + for (unsigned i : indices(indiceTypes)) { + auto ty = indiceTypes[i]; + auto &ti = IGF.getTypeInfo(ty); + auto ptr = IGF.Builder.CreateInBoundsGEP(argsBuf.getAddress() + ->getType() + ->getScalarType() + ->getPointerElementType(), + argsBuf.getAddress(), + operandOffsets[i]); + auto addr = ti.getAddressForPointer( + IGF.Builder.CreateBitCast(ptr, ti.getStorageType()->getPointerTo())); + if (ty.isAddress()) { + ti.initializeWithTake(IGF, addr, + ti.getAddressForPointer(indiceValues.claimNext()), + ty, false); + } else { + cast(ti).initialize(IGF, indiceValues, addr, false); + } + } + return std::make_pair(argsBuf.getAddress(), argsBufSize); + } else { + // No arguments necessary, so the argument ought to be ignored by any + // callbacks in the pattern. + assert(indiceTypes.empty() && "indices not implemented"); + return std::make_pair(llvm::UndefValue::get(IGM.Int8PtrTy), + llvm::ConstantInt::get(IGM.SizeTy, 0)); + } +} diff --git a/lib/IRGen/GenKeyPath.h b/lib/IRGen/GenKeyPath.h new file mode 100644 index 0000000000000..27931279c53a7 --- /dev/null +++ b/lib/IRGen/GenKeyPath.h @@ -0,0 +1,55 @@ +//===--- GenBuiltin.h - IR generation for builtin functions -----*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// +// +// This file provides the private interface to the emission of KeyPath +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_IRGEN_GENKEYPATH_H +#define SWIFT_IRGEN_GENKEYPATH_H + +#include "Address.h" +#include "GenericRequirement.h" +#include "swift/AST/SubstitutionMap.h" +#include "swift/Basic/LLVM.h" +#include "swift/SIL/SILValue.h" +#include "llvm/IR/Value.h" + +namespace swift { + class BuiltinInfo; + class BuiltinInst; + class Identifier; + class KeyPathPattern; + +namespace irgen { + class Explosion; + class IRGenFunction; + class StackAddress; + + class KeyPathArgumentEmission { + IRGenFunction &IGF; + const KeyPathPattern &pattern; + public: + KeyPathArgumentEmission(IRGenFunction &IGF, const KeyPathPattern &pattern) + : IGF(IGF), pattern(pattern) {} + llvm::Value *begin(SubstitutionMap subs, ArrayRef indiceOperands); + void emitArgument(); + }; + std::pair emitKeyPathInstantiationArgument( + IRGenFunction &IGF, SubstitutionMap subs, const CanGenericSignature &sig, + ArrayRef indiceTypes, Explosion &indiceValues, + Optional &dynamicArgsBuf, + EmitGenericRequirementFn emitRequirement); +} // end namespace irgen +} // end namespace swift + +#endif diff --git a/lib/IRGen/GenPointerAuth.cpp b/lib/IRGen/GenPointerAuth.cpp index e118806d6e09b..099f1e36eca86 100644 --- a/lib/IRGen/GenPointerAuth.cpp +++ b/lib/IRGen/GenPointerAuth.cpp @@ -199,6 +199,10 @@ static const PointerAuthSchema &getFunctionPointerSchema(IRGenModule &IGM, case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: if (fnType->isAsync()) { return options.AsyncSwiftFunctionPointers; } @@ -578,7 +582,11 @@ PointerAuthEntity::getTypeDiscriminator(IRGenModule &IGM) const { case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: - case SILFunctionTypeRepresentation::Closure: { + case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: { llvm::ConstantInt *&cache = IGM.getPointerAuthCaches().Types[fnType]; if (cache) return cache; diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index a0b46a5d9a278..8eeb39fa75523 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -2318,6 +2318,10 @@ bool irgen::hasPolymorphicParameters(CanSILFunctionType ty) { case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return ty->isPolymorphic(); case SILFunctionTypeRepresentation::CFunctionPointer: diff --git a/lib/IRGen/GenericRequirement.h b/lib/IRGen/GenericRequirement.h index c617cee66f5ea..718efac085042 100644 --- a/lib/IRGen/GenericRequirement.h +++ b/lib/IRGen/GenericRequirement.h @@ -87,6 +87,13 @@ void bindFromGenericRequirementsBuffer(IRGenFunction &IGF, MetadataState metadataState, GetTypeParameterInContextFn getInContext); +void bindPolymorphicArgumentsFromComponentIndices(IRGenFunction &IGF, + GenericEnvironment *genericEnv, + ArrayRef requirements, + llvm::Value *args, + llvm::Value *size, + bool hasSubscriptIndices); + /// A class describing the layout of the generic requirements of a /// nominal type metadata. diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index 9a801e19fedef..eae19baa44dc3 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -15,6 +15,8 @@ // //===----------------------------------------------------------------------===// +#include "GenKeyPath.h" +#include "swift/AST/ExtInfo.h" #define DEBUG_TYPE "irgensil" #include "swift/AST/ASTContext.h" @@ -2040,6 +2042,76 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, llvm::Value *contextPtr = emission->getContext(); (void)contextPtr; assert(contextPtr->getType() == IGF.IGM.RefCountedPtrTy); + } else if (isKeyPathAccessorRepresentation(funcTy->getRepresentation())) { + auto genericEnv = IGF.CurSILFn->getGenericEnvironment(); + SmallVector requirements; + CanGenericSignature genericSig; + if (genericEnv) { + genericSig = IGF.CurSILFn->getGenericSignature().getCanonicalSignature(); + enumerateGenericSignatureRequirements(genericSig, + [&](GenericRequirement reqt) { requirements.push_back(reqt); }); + } + + unsigned baseIndexOfIndicesArguments; + unsigned numberOfIndicesArguments; + switch (funcTy->getRepresentation()) { + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + baseIndexOfIndicesArguments = 1; + numberOfIndicesArguments = 1; + break; + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + baseIndexOfIndicesArguments = 2; + numberOfIndicesArguments = 1; + break; + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + baseIndexOfIndicesArguments = 0; + numberOfIndicesArguments = 2; + break; + case SILFunctionTypeRepresentation::KeyPathAccessorHash: + baseIndexOfIndicesArguments = 0; + numberOfIndicesArguments = 1; + break; + default: + llvm_unreachable("unhandled keypath accessor representation"); + } + + llvm::Value *componentArgsBufSize = allParamValues.takeLast(); + llvm::Value *componentArgsBuf; + bool hasSubscriptIndices = params.size() > baseIndexOfIndicesArguments; + + // Bind the indices arguments if present. + if (hasSubscriptIndices) { + assert(baseIndexOfIndicesArguments + numberOfIndicesArguments == params.size()); + + for (unsigned i = 0; i < numberOfIndicesArguments; ++i) { + SILArgument *indicesArg = params[baseIndexOfIndicesArguments + i]; + componentArgsBuf = allParamValues.takeLast(); + bindParameter( + IGF, *emission, baseIndexOfIndicesArguments + i, indicesArg, + conv.getSILArgumentType(baseIndexOfIndicesArguments + i, + IGF.IGM.getMaximalTypeExpansionContext()), + [&](unsigned startIndex, unsigned size) { + assert(size == 1); + Explosion indicesTemp; + auto castedIndices = + IGF.Builder.CreateBitCast( + componentArgsBuf, IGF.getTypeInfo(indicesArg->getType()).getStorageType()->getPointerTo()); + indicesTemp.add(castedIndices); + return indicesTemp; + }); + } + params = params.drop_back(numberOfIndicesArguments); + } else { + // Discard the trailing unbound LLVM IR arguments. + for (unsigned i = 0; i < numberOfIndicesArguments; ++i) { + componentArgsBuf = allParamValues.takeLast(); + } + } + bindPolymorphicArgumentsFromComponentIndices(IGF, genericEnv, + requirements, + componentArgsBuf, + componentArgsBufSize, + hasSubscriptIndices); } // Map the remaining SIL parameters to LLVM parameters. @@ -2057,7 +2129,8 @@ static void emitEntryPointArgumentsNativeCC(IRGenSILFunction &IGF, // Bind polymorphic arguments. This can only be done after binding // all the value parameters. - if (hasPolymorphicParameters(funcTy)) { + if (hasPolymorphicParameters(funcTy) + && !isKeyPathAccessorRepresentation(funcTy->getRepresentation())) { emitPolymorphicParameters( IGF, *IGF.CurSILFn, *emission, &witnessMetadata, [&](unsigned paramIndex) -> llvm::Value * { @@ -2999,6 +3072,10 @@ Callee LoweredValue::getCallee(IRGenFunction &IGF, case SILFunctionType::Representation::Thin: case SILFunctionType::Representation::Closure: case SILFunctionType::Representation::Method: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: return getSwiftFunctionPointerCallee(IGF, functionValue, selfValue, std::move(calleeInfo), false); @@ -3060,6 +3137,10 @@ static std::unique_ptr getCallEmissionForLoweredValue( case SILFunctionType::Representation::CFunctionPointer: case SILFunctionType::Representation::Method: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: break; } @@ -3438,6 +3519,10 @@ getPartialApplicationFunction(IRGenSILFunction &IGF, SILValue v, case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: break; } @@ -6437,85 +6522,23 @@ void IRGenSILFunction::visitKeyPathInst(swift::KeyPathInst *I) { auto pattern = IGM.getAddrOfKeyPathPattern(I->getPattern(), I->getLoc()); // Build up the argument vector to instantiate the pattern here. Optional dynamicArgsBuf; - llvm::Value *args; - if (!I->getSubstitutions().empty() || !I->getAllOperands().empty()) { - auto sig = I->getPattern()->getGenericSignature(); - SubstitutionMap subs = I->getSubstitutions(); - - SmallVector requirements; - enumerateGenericSignatureRequirements(sig, - [&](GenericRequirement reqt) { requirements.push_back(reqt); }); - llvm::Value *argsBufSize; - llvm::Value *argsBufAlign; - - if (!I->getSubstitutions().empty()) { - argsBufSize = llvm::ConstantInt::get(IGM.SizeTy, - IGM.getPointerSize().getValue() * requirements.size()); - argsBufAlign = llvm::ConstantInt::get(IGM.SizeTy, - IGM.getPointerAlignment().getMaskValue()); - } else { - argsBufSize = llvm::ConstantInt::get(IGM.SizeTy, 0); - argsBufAlign = llvm::ConstantInt::get(IGM.SizeTy, 0); - } - - SmallVector operandOffsets; - for (unsigned i : indices(I->getAllOperands())) { - auto operand = I->getAllOperands()[i].get(); - auto &ti = getTypeInfo(operand->getType()); - auto ty = operand->getType(); - auto alignMask = ti.getAlignmentMask(*this, ty); - if (i != 0) { - auto notAlignMask = Builder.CreateNot(alignMask); - argsBufSize = Builder.CreateAdd(argsBufSize, alignMask); - argsBufSize = Builder.CreateAnd(argsBufSize, notAlignMask); - } - operandOffsets.push_back(argsBufSize); - auto size = ti.getSize(*this, ty); - argsBufSize = Builder.CreateAdd(argsBufSize, size); - argsBufAlign = Builder.CreateOr(argsBufAlign, alignMask); - } + SmallVector indiceTypes; + Explosion indiceValues; + for (auto &operand : I->getAllOperands()) { + indiceTypes.push_back(operand.get()->getType()); + getLoweredExplosion(operand.get(), indiceValues); + } + auto sig = I->getPattern()->getGenericSignature(); + auto subs = I->getSubstitutions(); + auto args = emitKeyPathInstantiationArgument( + *this, subs, sig, indiceTypes, indiceValues, dynamicArgsBuf, + [&](GenericRequirement reqt) -> llvm::Value * { + return emitGenericRequirementFromSubstitutions(*this, sig, reqt, subs); + }); - dynamicArgsBuf = emitDynamicAlloca(IGM.Int8Ty, argsBufSize, Alignment(16)); - - Address argsBuf = dynamicArgsBuf->getAddress(); - - if (!I->getSubstitutions().empty()) { - emitInitOfGenericRequirementsBuffer(*this, requirements, argsBuf, - [&](GenericRequirement reqt) -> llvm::Value * { - return emitGenericRequirementFromSubstitutions(*this, sig, - reqt, subs); - }); - } - - for (unsigned i : indices(I->getAllOperands())) { - auto operand = I->getAllOperands()[i].get(); - auto &ti = getTypeInfo(operand->getType()); - auto ptr = - Builder.CreateInBoundsGEP(argsBuf.getAddress() - ->getType() - ->getScalarType() - ->getPointerElementType(), - argsBuf.getAddress(), operandOffsets[i]); - auto addr = ti.getAddressForPointer( - Builder.CreateBitCast(ptr, ti.getStorageType()->getPointerTo())); - if (operand->getType().isAddress()) { - ti.initializeWithTake(*this, addr, getLoweredAddress(operand), - operand->getType(), false); - } else { - Explosion operandValue = getLoweredExplosion(operand); - cast(ti).initialize(*this, operandValue, addr, false); - } - } - args = argsBuf.getAddress(); - } else { - // No arguments necessary, so the argument ought to be ignored by any - // callbacks in the pattern. - assert(I->getAllOperands().empty() && "indices not implemented"); - args = llvm::UndefValue::get(IGM.Int8PtrTy); - } auto patternPtr = llvm::ConstantExpr::getBitCast(pattern, IGM.Int8PtrTy); - auto call = Builder.CreateCall(IGM.getGetKeyPathFn(), {patternPtr, args}); + auto call = Builder.CreateCall(IGM.getGetKeyPathFn(), {patternPtr, args.first}); call->setDoesNotThrow(); if (dynamicArgsBuf) { diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp index b91cc2106c4a7..74adab249ac9a 100644 --- a/lib/IRGen/MetadataRequest.cpp +++ b/lib/IRGen/MetadataRequest.cpp @@ -3221,6 +3221,10 @@ class EmitTypeMetadataRefForLayout case SILFunctionType::Representation::CXXMethod: case SILFunctionType::Representation::CFunctionPointer: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: // A thin function looks like a plain pointer. // FIXME: Except for extra inhabitants? return C.TheRawPointerType; @@ -3425,6 +3429,10 @@ namespace { case SILFunctionType::Representation::CXXMethod: case SILFunctionType::Representation::CFunctionPointer: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: // A thin function looks like a plain pointer. // FIXME: Except for extra inhabitants? return emitFromValueWitnessTable(C.TheRawPointerType); diff --git a/lib/SIL/IR/Bridging.cpp b/lib/SIL/IR/Bridging.cpp index 7dac4efc52ba0..7bf056050b2b0 100644 --- a/lib/SIL/IR/Bridging.cpp +++ b/lib/SIL/IR/Bridging.cpp @@ -101,6 +101,10 @@ Type TypeConverter::getLoweredBridgedType(AbstractionPattern pattern, case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: // No bridging needed for native CCs. return t; case SILFunctionTypeRepresentation::CFunctionPointer: @@ -186,6 +190,10 @@ Type TypeConverter::getLoweredCBridgedType(AbstractionPattern pattern, case SILFunctionTypeRepresentation::CXXMethod: case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: return t; case SILFunctionType::Representation::Thick: { // Thick functions (TODO: conditionally) get bridged to blocks. diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 5e8cc7da26da6..698e5bb9c48d8 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -2359,6 +2359,10 @@ static CanSILFunctionType getNativeSILFunctionType( case SILFunctionType::Representation::Thick: case SILFunctionType::Representation::Method: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: case SILFunctionType::Representation::WitnessMethod: { switch (origConstant ? origConstant->kind : SILDeclRef::Kind::Func) { case SILDeclRef::Kind::Initializer: @@ -4469,6 +4473,10 @@ TypeConverter::getLoweredFormalTypes(SILDeclRef constant, case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::Closure: case SILFunctionTypeRepresentation::WitnessMethod: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: // Native functions don't need bridging. bridgedParams.append(methodParams.begin(), methodParams.end()); bridgedResultType = resultType; diff --git a/lib/SIL/Utils/InstructionUtils.cpp b/lib/SIL/Utils/InstructionUtils.cpp index 0d2020154b78f..3e9fb1f3fa674 100644 --- a/lib/SIL/Utils/InstructionUtils.cpp +++ b/lib/SIL/Utils/InstructionUtils.cpp @@ -777,6 +777,10 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType) case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::Closure: case SILFunctionTypeRepresentation::Thick: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: break; } diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index 6b29fe6717477..094cb022fbdb5 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -173,15 +173,17 @@ void verifyKeyPathComponent(SILModule &M, auto substEqualsType = equals->getLoweredFunctionType() ->substGenericArgs(M, patternSubs, TypeExpansionContext::minimal()); + require(substEqualsType->getRepresentation() == + SILFunctionTypeRepresentation::KeyPathAccessorEquals, + "equals should be a keypath equals convention"); + require(substEqualsType->getParameters().size() == 2, "must have two arguments"); for (unsigned i = 0; i < 2; ++i) { auto param = substEqualsType->getParameters()[i]; require(param.getConvention() - == ParameterConvention::Direct_Unowned, - "indices pointer should be trivial"); - require(param.getInterfaceType()->isUnsafeRawPointer(), - "indices pointer should be an UnsafeRawPointer"); + == ParameterConvention::Indirect_In_Guaranteed, + "indices pointer should be in_guaranteed"); } require(substEqualsType->getResults().size() == 1, @@ -203,15 +205,16 @@ void verifyKeyPathComponent(SILModule &M, auto substHashType = hash->getLoweredFunctionType() ->substGenericArgs(M, patternSubs, TypeExpansionContext::minimal()); + require(substHashType->getRepresentation() == + SILFunctionTypeRepresentation::KeyPathAccessorHash, + "hash should be a keypath hash convention"); require(substHashType->getParameters().size() == 1, "must have two arguments"); auto param = substHashType->getParameters()[0]; require(param.getConvention() - == ParameterConvention::Direct_Unowned, - "indices pointer should be trivial"); - require(param.getInterfaceType()->isUnsafeRawPointer(), - "indices pointer should be an UnsafeRawPointer"); - + == ParameterConvention::Indirect_In_Guaranteed, + "indices pointer should be in_guaranteed"); + require(substHashType->getResults().size() == 1, "must have one result"); @@ -286,8 +289,8 @@ void verifyKeyPathComponent(SILModule &M, auto substGetterType = getter->getLoweredFunctionType()->substGenericArgs( M, patternSubs, TypeExpansionContext::minimal()); require(substGetterType->getRepresentation() == - SILFunctionTypeRepresentation::Thin, - "getter should be a thin function"); + SILFunctionTypeRepresentation::KeyPathAccessorGetter, + "getter should be a keypath getter convention"); require(substGetterType->getNumParameters() == 1 + hasIndices, "getter should have one parameter"); @@ -302,13 +305,8 @@ void verifyKeyPathComponent(SILModule &M, if (hasIndices) { auto indicesParam = substGetterType->getParameters()[1]; require(indicesParam.getConvention() - == ParameterConvention::Direct_Unowned, - "indices pointer should be trivial"); - require( - indicesParam - .getArgumentType(M, substGetterType, typeExpansionContext) - ->isUnsafeRawPointer(), - "indices pointer should be an UnsafeRawPointer"); + == ParameterConvention::Indirect_In_Guaranteed, + "indices should be in_guaranteed"); } require(substGetterType->getNumResults() == 1, @@ -338,8 +336,8 @@ void verifyKeyPathComponent(SILModule &M, ->substGenericArgs(M, patternSubs, TypeExpansionContext::minimal()); require(substSetterType->getRepresentation() == - SILFunctionTypeRepresentation::Thin, - "setter should be a thin function"); + SILFunctionTypeRepresentation::KeyPathAccessorSetter, + "setter should be keypath setter convention"); require(substSetterType->getNumParameters() == 2 + hasIndices, "setter should have two parameters"); @@ -360,13 +358,8 @@ void verifyKeyPathComponent(SILModule &M, if (hasIndices) { auto indicesParam = substSetterType->getParameters()[2]; require(indicesParam.getConvention() - == ParameterConvention::Direct_Unowned, - "indices pointer should be trivial"); - require( - indicesParam - .getArgumentType(M, substSetterType, typeExpansionContext) - ->isUnsafeRawPointer(), - "indices pointer should be an UnsafeRawPointer"); + == ParameterConvention::Indirect_In_Guaranteed, + "indices pointer should be in_guaranteed"); } require(getTypeInExpansionContext(newValueParam.getArgumentType( diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index ebd8c7fa02204..51cacbd4f76d2 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -37,6 +37,7 @@ #include "swift/AST/ParameterList.h" #include "swift/AST/ProtocolConformance.h" #include "swift/AST/SubstitutionMap.h" +#include "swift/AST/Type.h" #include "swift/AST/Types.h" #include "swift/Basic/SourceManager.h" #include "swift/Basic/type_traits.h" @@ -1671,6 +1672,10 @@ static ManagedValue convertFunctionRepresentation(SILGenFunction &SGF, case SILFunctionType::Representation::ObjCMethod: case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::CXXMethod: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: llvm_unreachable("should not do function conversion from method rep"); } llvm_unreachable("bad representation"); @@ -1701,6 +1706,10 @@ static ManagedValue convertFunctionRepresentation(SILGenFunction &SGF, case SILFunctionType::Representation::ObjCMethod: case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::CXXMethod: + case SILFunctionType::Representation::KeyPathAccessorGetter: + case SILFunctionType::Representation::KeyPathAccessorSetter: + case SILFunctionType::Representation::KeyPathAccessorEquals: + case SILFunctionType::Representation::KeyPathAccessorHash: llvm_unreachable("should not do function conversion from method rep"); } llvm_unreachable("bad representation"); @@ -2750,7 +2759,7 @@ static PreparedArguments loadIndexValuesForKeyPathComponent(SILGenFunction &SGF, SILLocation loc, AbstractStorageDecl *storage, ArrayRef indexes, - SILValue pointer) { + SILValue pointer, bool skipTupleCast = false) { // If not a subscript, do nothing. if (!isa(storage)) return PreparedArguments(); @@ -2771,9 +2780,14 @@ loadIndexValuesForKeyPathComponent(SILGenFunction &SGF, SILLocation loc, SGF.getLoweredType( AnyFunctionType::composeTuple(SGF.getASTContext(), indexParams)); - auto addr = SGF.B.createPointerToAddress(loc, pointer, - indexLoweredTy.getAddressType(), - /*isStrict*/ false); + SILValue addr; + if (skipTupleCast) { + addr = pointer; + } else { + addr = SGF.B.createPointerToAddress(loc, pointer, + indexLoweredTy.getAddressType(), + /*isStrict*/ false); + } for (unsigned i : indices(indexes)) { SILValue eltAddr = addr; @@ -2801,6 +2815,15 @@ getRepresentativeAccessorForKeyPath(AbstractStorageDecl *storage) { return storage->getOpaqueAccessor(AccessorKind::Read); } +static CanType +buildKeyPathIndicesTuple(ASTContext &C, ArrayRef indexes) { + SmallVector indicesElements; + for (auto &elt : indexes) { + indicesElements.emplace_back(elt.first); + } + return TupleType::get(indicesElements, C)->getCanonicalType(); +} + static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM, AbstractStorageDecl *property, SubstitutionMap subs, @@ -2826,7 +2849,6 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM, } } - auto Target = SGM.getASTContext().LangOpts.Target; auto genericSig = genericEnv ? genericEnv->getGenericSignature().getCanonicalSignature() : nullptr; @@ -2835,14 +2857,6 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM, genericEnv = nullptr; } - // Add empty generic type parameter to match function signature on WebAssembly - if (!genericSig && Target.isOSBinFormatWasm()) { - auto param = GenericTypeParamType::get(false, 0, 0, SGM.getASTContext()); - auto sig = GenericSignature::get(param, { }); - genericSig = CanGenericSignature(sig); - genericEnv = sig.getGenericEnvironment(); - } - // Build the signature of the thunk as expected by the keypath runtime. auto signature = [&]() { CanType loweredBaseTy, loweredPropTy; @@ -2858,15 +2872,16 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM, SmallVector params; params.push_back({loweredBaseTy, paramConvention}); auto &C = SGM.getASTContext(); - // Always take indexes parameter to match callee and caller signature on WebAssembly - if (!indexes.empty() || C.LangOpts.Target.isOSBinFormatWasm()) - params.push_back({C.getUnsafeRawPointerType()->getCanonicalType(), - ParameterConvention::Direct_Unowned}); - + + if (!indexes.empty()) { + params.push_back({buildKeyPathIndicesTuple(C, indexes), paramConvention}); + } + SILResultInfo result(loweredPropTy, ResultConvention::Indirect); return SILFunctionType::get(genericSig, - SILFunctionType::ExtInfo::getThin(), + SILFunctionType::ExtInfo().withRepresentation( + SILFunctionType::Representation::KeyPathAccessorGetter), SILCoroutineKind::None, ParameterConvention::Direct_Unowned, params, {}, result, None, @@ -2916,10 +2931,11 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM, auto resultArg = entry->createFunctionArgument(resultArgTy); auto baseArg = entry->createFunctionArgument(baseArgTy); SILValue indexPtrArg; - // Always take indexes parameter to match callee and caller signature on WebAssembly - if (!indexes.empty() || Target.isOSBinFormatWasm()) { + if (!indexes.empty()) { auto indexArgTy = signature->getParameters()[1].getSILStorageType( SGM.M, signature, subSGF.F.getTypeExpansionContext()); + if (genericEnv) + indexArgTy = genericEnv->mapTypeIntoContext(SGM.M, indexArgTy); indexPtrArg = entry->createFunctionArgument(indexArgTy); } @@ -2930,7 +2946,7 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM, baseType, subs); auto subscriptIndices = loadIndexValuesForKeyPathComponent(subSGF, loc, property, - indexes, indexPtrArg); + indexes, indexPtrArg, true); ManagedValue resultSubst; { @@ -3000,7 +3016,6 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM, } } - auto Target = SGM.getASTContext().LangOpts.Target; auto genericSig = genericEnv ? genericEnv->getGenericSignature().getCanonicalSignature() : nullptr; @@ -3009,14 +3024,6 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM, genericEnv = nullptr; } - // Add empty generic type parameter to match function signature on WebAssembly - if (!genericSig && Target.isOSBinFormatWasm()) { - auto param = GenericTypeParamType::get(false, 0, 0, SGM.getASTContext()); - auto sig = GenericSignature::get(param, { }); - genericSig = CanGenericSignature(sig); - genericEnv = sig.getGenericEnvironment(); - } - // Build the signature of the thunk as expected by the keypath runtime. auto signature = [&]() { CanType loweredBaseTy, loweredPropTy; @@ -3042,13 +3049,13 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM, ? ParameterConvention::Indirect_Inout : paramConvention}); // indexes - // Always take indexes parameter to match callee and caller signature on WebAssembly - if (!indexes.empty() || C.LangOpts.Target.isOSBinFormatWasm()) - params.push_back({C.getUnsafeRawPointerType()->getCanonicalType(), - ParameterConvention::Direct_Unowned}); + if (!indexes.empty()) { + params.push_back({buildKeyPathIndicesTuple(C, indexes), paramConvention}); + } return SILFunctionType::get(genericSig, - SILFunctionType::ExtInfo::getThin(), + SILFunctionType::ExtInfo().withRepresentation( + SILFunctionType::Representation::KeyPathAccessorSetter), SILCoroutineKind::None, ParameterConvention::Direct_Unowned, params, {}, {}, None, @@ -3099,10 +3106,11 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM, auto baseArg = entry->createFunctionArgument(baseArgTy); SILValue indexPtrArg; - // Always take indexes parameter to match callee and caller signature on WebAssembly - if (!indexes.empty() || Target.isOSBinFormatWasm()) { + if (!indexes.empty()) { auto indexArgTy = signature->getParameters()[2].getSILStorageType( SGM.M, signature, subSGF.getTypeExpansionContext()); + if (genericEnv) + indexArgTy = genericEnv->mapTypeIntoContext(SGM.M, indexArgTy); indexPtrArg = entry->createFunctionArgument(indexArgTy); } @@ -3110,7 +3118,7 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM, auto subscriptIndices = loadIndexValuesForKeyPathComponent(subSGF, loc, property, - indexes, indexPtrArg); + indexes, indexPtrArg, true); auto valueOrig = ManagedValue::forBorrowedRValue(valueArg) .copy(subSGF, loc); @@ -3174,6 +3182,7 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, GenericEnvironment *genericEnv, ResilienceExpansion expansion, ArrayRef indexes, + ArrayRef newIndexes, SILFunction *&equals, SILFunction *&hash) { if (indexes.empty()) { @@ -3182,7 +3191,6 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, return; } - auto Target = SGM.getASTContext().LangOpts.Target; auto genericSig = genericEnv ? genericEnv->getGenericSignature().getCanonicalSignature() : nullptr; @@ -3192,14 +3200,6 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, genericEnv = nullptr; } - // Add empty generic type parameter to match function signature on WebAssembly - if (!genericSig && Target.isOSBinFormatWasm()) { - auto param = GenericTypeParamType::get(false, 0, 0, SGM.getASTContext()); - auto sig = GenericSignature::get(param, { }); - genericSig = CanGenericSignature(sig); - genericEnv = sig.getGenericEnvironment(); - } - auto &C = SGM.getASTContext(); auto unsafeRawPointerTy = C.getUnsafeRawPointerType()->getCanonicalType(); auto boolTy = C.getBoolType()->getCanonicalType(); @@ -3228,19 +3228,19 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, // Get or create the equals witness [unsafeRawPointerTy, boolTy, genericSig, &C, &indexTypes, &equals, loc, - &SGM, genericEnv, expansion, indexLoweredTy, indexes]{ - // (RawPointer, RawPointer) -> Bool + &SGM, genericEnv, expansion, indexLoweredTy, indexes, newIndexes]{ + // (lhs: (X, Y, ...), rhs: (X, Y, ...)) -> Bool SmallVector params; - params.push_back({unsafeRawPointerTy, - ParameterConvention::Direct_Unowned}); - params.push_back({unsafeRawPointerTy, - ParameterConvention::Direct_Unowned}); + auto indicesTuple = buildKeyPathIndicesTuple(C, newIndexes); + params.push_back({indicesTuple, ParameterConvention::Indirect_In_Guaranteed}); + params.push_back({indicesTuple, ParameterConvention::Indirect_In_Guaranteed}); SmallVector results; results.push_back({boolTy, ResultConvention::Unowned}); auto signature = SILFunctionType::get(genericSig, - SILFunctionType::ExtInfo::getThin(), + SILFunctionType::ExtInfo().withRepresentation( + SILFunctionType::Representation::KeyPathAccessorEquals), SILCoroutineKind::None, ParameterConvention::Direct_Unowned, params, /*yields*/ {}, results, None, @@ -3264,19 +3264,21 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, SILGenFunction subSGF(SGM, *equals, SGM.SwiftModule); equals->setGenericEnvironment(genericEnv); auto entry = equals->begin(); - auto lhsPtr = entry->createFunctionArgument(params[0].getSILStorageType( - SGM.M, signature, subSGF.getTypeExpansionContext())); - auto rhsPtr = entry->createFunctionArgument(params[1].getSILStorageType( - SGM.M, signature, subSGF.getTypeExpansionContext())); + auto lhsArgTy = params[0].getSILStorageType( + SGM.M, signature, subSGF.getTypeExpansionContext()); + auto rhsArgTy = params[1].getSILStorageType( + SGM.M, signature, subSGF.getTypeExpansionContext()); + if (genericEnv) { + lhsArgTy = genericEnv->mapTypeIntoContext(SGM.M, lhsArgTy); + rhsArgTy = genericEnv->mapTypeIntoContext(SGM.M, rhsArgTy); + } + auto lhsPtr = entry->createFunctionArgument(lhsArgTy); + auto rhsPtr = entry->createFunctionArgument(rhsArgTy); Scope scope(subSGF, loc); - auto lhsAddr = subSGF.B.createPointerToAddress(loc, lhsPtr, - indexLoweredTy, - /*isStrict*/ false); - auto rhsAddr = subSGF.B.createPointerToAddress(loc, rhsPtr, - indexLoweredTy, - /*isStrict*/ false); + auto lhsAddr = lhsPtr; + auto rhsAddr = rhsPtr; // Compare each pair of index values using the == witness from the // conformance. @@ -3406,17 +3408,17 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, // Get or create the hash witness [unsafeRawPointerTy, intTy, genericSig, &C, indexTypes, &hash, &loc, - &SGM, genericEnv, expansion, indexLoweredTy, hashableProto, indexes]{ - // (RawPointer) -> Int + &SGM, genericEnv, expansion, indexLoweredTy, hashableProto, indexes, newIndexes]{ + // (indices: (X, Y, ...)) -> Int SmallVector params; - params.push_back({unsafeRawPointerTy, - ParameterConvention::Direct_Unowned}); + params.push_back({buildKeyPathIndicesTuple(C, newIndexes), ParameterConvention::Indirect_In_Guaranteed}); SmallVector results; results.push_back({intTy, ResultConvention::Unowned}); auto signature = SILFunctionType::get(genericSig, - SILFunctionType::ExtInfo::getThin(), + SILFunctionType::ExtInfo().withRepresentation( + SILFunctionType::Representation::KeyPathAccessorHash), SILCoroutineKind::None, ParameterConvention::Direct_Unowned, params, /*yields*/ {}, results, None, @@ -3441,8 +3443,11 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, SILGenFunction subSGF(SGM, *hash, SGM.SwiftModule); hash->setGenericEnvironment(genericEnv); auto entry = hash->begin(); - auto indexPtr = entry->createFunctionArgument(params[0].getSILStorageType( - SGM.M, signature, subSGF.getTypeExpansionContext())); + auto indexArgTy = params[0].getSILStorageType( + SGM.M, signature, subSGF.getTypeExpansionContext()); + if (genericEnv) + indexArgTy = genericEnv->mapTypeIntoContext(SGM.M, indexArgTy); + auto indexPtr = entry->createFunctionArgument(indexArgTy); SILValue hashCode; @@ -3454,9 +3459,7 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, auto &index = indexes[0]; // Extract the index value. - SILValue indexAddr = subSGF.B.createPointerToAddress(loc, indexPtr, - indexLoweredTy, - /*isStrict*/ false); + SILValue indexAddr = indexPtr; if (indexes.size() > 1) { indexAddr = subSGF.B.createTupleElementAddr(loc, indexAddr, 0); } @@ -3786,7 +3789,7 @@ SILGenModule::emitKeyPathComponentForDecl(SILLocation loc, getOrCreateKeyPathEqualsAndHash(*this, loc, needsGenericContext ? genericEnv : nullptr, expansion, - indexPatterns, + indexPatterns, indexTypes, indexEquals, indexHash); } diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp index 695596b117d55..08a54e4016fb6 100644 --- a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp +++ b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp @@ -85,6 +85,10 @@ static bool isSpecializableRepresentation(SILFunctionTypeRepresentation Rep, case SILFunctionTypeRepresentation::Thick: case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::CXXMethod: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: return true; case SILFunctionTypeRepresentation::WitnessMethod: return OptForPartialApply; diff --git a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp index 9be79987291d0..1b0dc071268f6 100644 --- a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp +++ b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp @@ -711,6 +711,10 @@ getCalleeFunction(SILFunction *F, FullApplySite AI, bool &IsThick, case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::Closure: case SILFunctionTypeRepresentation::WitnessMethod: + case SILFunctionTypeRepresentation::KeyPathAccessorGetter: + case SILFunctionTypeRepresentation::KeyPathAccessorSetter: + case SILFunctionTypeRepresentation::KeyPathAccessorEquals: + case SILFunctionTypeRepresentation::KeyPathAccessorHash: break; case SILFunctionTypeRepresentation::CFunctionPointer: diff --git a/lib/SILOptimizer/Utils/KeyPathProjector.cpp b/lib/SILOptimizer/Utils/KeyPathProjector.cpp index f66ed98396c14..6051ae07d3e5b 100644 --- a/lib/SILOptimizer/Utils/KeyPathProjector.cpp +++ b/lib/SILOptimizer/Utils/KeyPathProjector.cpp @@ -233,22 +233,7 @@ class GettablePropertyProjector : public ComponentProjector { assert(getter->getConventions().getNumSILArguments()); auto ref = builder.createFunctionRef(loc, getter); - - std::vector args{addr, parentValue}; - // FIXME(wasm): For wasm, KeyPath getter always take indices parameter - // to match callee and caller signature. So need to pass stub pointer. - // See also: getOrCreateKeyPathSetter and getOrCreateKeyPathGetter - if (builder.getASTContext().LangOpts.Target.isOSBinFormatWasm()) { - auto IntTy = SILType::getBuiltinIntegerType(32, builder.getASTContext()); - auto UnsafeRawPointerTy = SILType::getRawPointerType(builder.getASTContext()); - auto zeroVal = SILValue(builder.createIntegerLiteral(loc, IntTy, 0)); - auto stackBuffer = SILValue(builder.createAllocStack(loc, IntTy)); - builder.createStore(loc, zeroVal, stackBuffer, StoreOwnershipQualifier::Unqualified); - auto nonePointer = builder.createUncheckedAddrCast(loc, stackBuffer, UnsafeRawPointerTy); - args.push_back(SILValue(nonePointer)); - } - - builder.createApply(loc, ref, subs, args); + builder.createApply(loc, ref, subs, {addr, parentValue}); // If we were previously accessing a class member, we're done now. insertEndAccess(beginAccess, builder); diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index a27d333d7a2db..c68b231f8e90f 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -2544,6 +2544,10 @@ TypeResolver::resolveAttributedType(TypeAttributes &attrs, TypeRepr *repr, SILFunctionType::Representation::ObjCMethod) .Case("witness_method", SILFunctionType::Representation::WitnessMethod) + .Case("keypath_accessor_getter", SILFunctionType::Representation::KeyPathAccessorGetter) + .Case("keypath_accessor_setter", SILFunctionType::Representation::KeyPathAccessorSetter) + .Case("keypath_accessor_equals", SILFunctionType::Representation::KeyPathAccessorEquals) + .Case("keypath_accessor_hash", SILFunctionType::Representation::KeyPathAccessorHash) .Default(None); if (!parsedRep) { diagnoseInvalid(repr, attrs.getLoc(TAK_convention), diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index c0dc9adf80392..78396c088b6f6 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -5149,6 +5149,10 @@ getActualSILFunctionTypeRepresentation(uint8_t rep) { CASE(ObjCMethod) CASE(WitnessMethod) CASE(CXXMethod) + CASE(KeyPathAccessorGetter) + CASE(KeyPathAccessorSetter) + CASE(KeyPathAccessorEquals) + CASE(KeyPathAccessorHash) #undef CASE default: return None; diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index f10ae02e230fb..4ad17d8173634 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 694; // add @objc protocol methods to objc method tables +const uint16_t SWIFTMODULE_VERSION_MINOR = 695; // Extend function representation bit width /// A standard hash seed used for all string hashes in a serialized module. /// @@ -278,8 +278,13 @@ enum class SILFunctionTypeRepresentation : uint8_t { WitnessMethod, Closure, CXXMethod, + KeyPathAccessorGetter, + KeyPathAccessorSetter, + KeyPathAccessorEquals, + KeyPathAccessorHash, }; -using SILFunctionTypeRepresentationField = BCFixed<4>; +// TODO(katei): Define SILFunctionTypeRepresentation::Last, and compute the bit width +using SILFunctionTypeRepresentationField = BCFixed<5>; // These IDs must \em not be renumbered or reordered without incrementing // the module version. diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index b974f0fd8f434..077b805e2fc5e 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -4298,6 +4298,10 @@ static uint8_t getRawStableSILFunctionTypeRepresentation( SIMPLE_CASE(SILFunctionTypeRepresentation, WitnessMethod) SIMPLE_CASE(SILFunctionTypeRepresentation, Closure) SIMPLE_CASE(SILFunctionTypeRepresentation, CXXMethod) + SIMPLE_CASE(SILFunctionTypeRepresentation, KeyPathAccessorGetter) + SIMPLE_CASE(SILFunctionTypeRepresentation, KeyPathAccessorSetter) + SIMPLE_CASE(SILFunctionTypeRepresentation, KeyPathAccessorEquals) + SIMPLE_CASE(SILFunctionTypeRepresentation, KeyPathAccessorHash) } llvm_unreachable("bad calling convention"); } diff --git a/test/Constraints/keypath_dynamic_member_lookup.swift b/test/Constraints/keypath_dynamic_member_lookup.swift index 7ba1166b9dc1a..dd36cf19e4f91 100644 --- a/test/Constraints/keypath_dynamic_member_lookup.swift +++ b/test/Constraints/keypath_dynamic_member_lookup.swift @@ -412,34 +412,34 @@ func testIUOUnwrap(_ x: SR_11893, _ y: SR_15249) { // CHECK: keypath $KeyPath, (root $SR_11893_Base; stored_property #SR_11893_Base.i : $Optional; optional_force : $Int) x.i - // CHECK: keypath $KeyPath, (root $SR_11893_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicig : $@convention(method) (Int, SR_11893_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicipACTK : $@convention(thin) (@in_guaranteed SR_11893_Base, UnsafeRawPointer) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int; optional_force : $Int) + // CHECK: keypath $KeyPath, (root $SR_11893_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicig : $@convention(method) (Int, SR_11893_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SR_11893_Base, @in_guaranteed Int) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; optional_force : $Int) x[5] // CHECK: [[INNER_KP:%[0-9]+]] = keypath $KeyPath, (root $SR_11893_Base; stored_property #SR_11893_Base.i : $Optional; optional_force : $Int) - // CHECK: keypath $KeyPath, (root $SR_11893; gettable_property $(), id @$s29keypath_dynamic_member_lookup8SR_11893V0B6Memberys7KeyPathCyAA0E11_11893_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, SR_11893) -> (), getter @$s29keypath_dynamic_member_lookup8SR_11893V0B6Memberys7KeyPathCyAA0E11_11893_BaseVSiG_tcipACTK : $@convention(thin) (@in_guaranteed SR_11893, UnsafeRawPointer) -> @out (), indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[INNER_KP]]) + // CHECK: keypath $KeyPath, (root $SR_11893; gettable_property $(), id @$s29keypath_dynamic_member_lookup8SR_11893V0B6Memberys7KeyPathCyAA0E11_11893_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, SR_11893) -> (), getter @$s29keypath_dynamic_member_lookup8SR_11893V0B6Memberys7KeyPathCyAA0E11_11893_BaseVSiG_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SR_11893, @in_guaranteed KeyPath) -> @out (), indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int) ([[INNER_KP]]) _ = \SR_11893.i - // CHECK: [[INNER_SUB_KP:%[0-9]+]] = keypath $KeyPath, (root $SR_11893_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicig : $@convention(method) (Int, SR_11893_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicipACTK : $@convention(thin) (@in_guaranteed SR_11893_Base, UnsafeRawPointer) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int; optional_force : $Int) - // CHECK: keypath $KeyPath, (root $SR_11893; gettable_property $(), id @$s29keypath_dynamic_member_lookup8SR_11893V0B6Memberys7KeyPathCyAA0E11_11893_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, SR_11893) -> (), getter @$s29keypath_dynamic_member_lookup8SR_11893V0B6Memberys7KeyPathCyAA0E11_11893_BaseVSiG_tcipACTK : $@convention(thin) (@in_guaranteed SR_11893, UnsafeRawPointer) -> @out (), indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[INNER_SUB_KP]]) + // CHECK: [[INNER_SUB_KP:%[0-9]+]] = keypath $KeyPath, (root $SR_11893_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicig : $@convention(method) (Int, SR_11893_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SR_11893_Base, @in_guaranteed Int) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; optional_force : $Int) + // CHECK: keypath $KeyPath, (root $SR_11893; gettable_property $(), id @$s29keypath_dynamic_member_lookup8SR_11893V0B6Memberys7KeyPathCyAA0E11_11893_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, SR_11893) -> (), getter @$s29keypath_dynamic_member_lookup8SR_11893V0B6Memberys7KeyPathCyAA0E11_11893_BaseVSiG_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SR_11893, @in_guaranteed KeyPath) -> @out (), indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int) ([[INNER_SUB_KP]]) _ = \SR_11893.[5] // SR-15249: Make sure we can handle IUO unwraps in both the inner and outer // key-paths. // CHECK: [[INNER_KP2:%[0-9]+]] = keypath $KeyPath, (root $SR_11893_Base; stored_property #SR_11893_Base.i : $Optional; optional_force : $Int) - // CHECK: keypath $KeyPath>, (root $SR_15249; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, SR_15249) -> Optional, getter @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcipACTK : $@convention(thin) (@in_guaranteed SR_15249, UnsafeRawPointer) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[INNER_KP2]]) + // CHECK: keypath $KeyPath>, (root $SR_15249; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, SR_15249) -> Optional, getter @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SR_15249, @in_guaranteed KeyPath) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int) ([[INNER_KP2]]) _ = \SR_15249.i // CHECK: [[INNER_KP3:%[0-9]+]] = keypath $KeyPath, (root $SR_11893_Base; stored_property #SR_11893_Base.i : $Optional; optional_force : $Int) - // CHECK: keypath $KeyPath, (root $SR_15249; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, SR_15249) -> Optional, getter @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcipACTK : $@convention(thin) (@in_guaranteed SR_15249, UnsafeRawPointer) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int; optional_force : $Int) ([[INNER_KP3]]) + // CHECK: keypath $KeyPath, (root $SR_15249; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, SR_15249) -> Optional, getter @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SR_15249, @in_guaranteed KeyPath) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int; optional_force : $Int) ([[INNER_KP3]]) let _: KeyPath = \SR_15249.i - // CHECK: [[INNER_KP4:%[0-9]+]] = keypath $KeyPath, (root $SR_11893_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicig : $@convention(method) (Int, SR_11893_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicipACTK : $@convention(thin) (@in_guaranteed SR_11893_Base, UnsafeRawPointer) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int; optional_force : $Int) - // CHECK: keypath $KeyPath>, (root $SR_15249; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, SR_15249) -> Optional, getter @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcipACTK : $@convention(thin) (@in_guaranteed SR_15249, UnsafeRawPointer) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[INNER_KP4]]) + // CHECK: [[INNER_KP4:%[0-9]+]] = keypath $KeyPath, (root $SR_11893_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicig : $@convention(method) (Int, SR_11893_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SR_11893_Base, @in_guaranteed Int) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; optional_force : $Int) + // CHECK: keypath $KeyPath>, (root $SR_15249; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, SR_15249) -> Optional, getter @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SR_15249, @in_guaranteed KeyPath) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int) ([[INNER_KP4]]) _ = \SR_15249.[0] - // CHECK: [[INNER_KP5:%[0-9]+]] = keypath $KeyPath, (root $SR_11893_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicig : $@convention(method) (Int, SR_11893_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicipACTK : $@convention(thin) (@in_guaranteed SR_11893_Base, UnsafeRawPointer) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int; optional_force : $Int) - // CHECK: keypath $KeyPath, (root $SR_15249; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, SR_15249) -> Optional, getter @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcipACTK : $@convention(thin) (@in_guaranteed SR_15249, UnsafeRawPointer) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int; optional_force : $Int) ([[INNER_KP5]]) + // CHECK: [[INNER_KP5:%[0-9]+]] = keypath $KeyPath, (root $SR_11893_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicig : $@convention(method) (Int, SR_11893_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SR_11893_Base, @in_guaranteed Int) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; optional_force : $Int) + // CHECK: keypath $KeyPath, (root $SR_15249; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcig : $@convention(method) (@guaranteed KeyPath, SR_15249) -> Optional, getter @$s29keypath_dynamic_member_lookup8SR_15249V0B6MemberSiSgs7KeyPathCyAA0E11_11893_BaseVSiG_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SR_15249, @in_guaranteed KeyPath) -> @out Optional, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup13SR_11893_BaseVSiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int; optional_force : $Int) ([[INNER_KP5]]) let _: KeyPath = \SR_15249.[0] // CHECK: [[INNER_KP6:%[0-9]+]] = keypath $KeyPath, (root $SR_11893_Base; stored_property #SR_11893_Base.i : $Optional; optional_force : $Int) @@ -449,7 +449,7 @@ func testIUOUnwrap(_ x: SR_11893, _ y: SR_15249) { // CHECK: bb{{[0-9]+}}(%{{[0-9]+}} : $Int) let _: Int = y.i - // CHECK: [[INNER_KP7:%[0-9]+]] = keypath $KeyPath, (root $SR_11893_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicig : $@convention(method) (Int, SR_11893_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicipACTK : $@convention(thin) (@in_guaranteed SR_11893_Base, UnsafeRawPointer) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int; optional_force : $Int) + // CHECK: [[INNER_KP7:%[0-9]+]] = keypath $KeyPath, (root $SR_11893_Base; gettable_property $Optional, id @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicig : $@convention(method) (Int, SR_11893_Base) -> Optional, getter @$s29keypath_dynamic_member_lookup13SR_11893_BaseVySiSgSicipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SR_11893_Base, @in_guaranteed Int) -> @out Optional, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; optional_force : $Int) // CHECK: [[Y0_OPT:%[0-9]+]] = apply {{%[0-9]+}}([[INNER_KP7]], {{%[0-9]+}}) : $@convention(method) (@guaranteed KeyPath, SR_15249) -> Optional // CHECK: switch_enum [[Y0_OPT]] // CHECK: unreachable @@ -510,15 +510,15 @@ struct SR_11933 { func testDynamicMemberWithDefault(_ x: SR_11933) { // CHECK: [[DEF_FN:%[0-9]+]] = function_ref @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipfA_ : $@convention(thin) () -> Int // CHECK: [[DEF_ARG:%[0-9]+]] = apply [[DEF_FN]]() - // CHECK: [[KP:%[0-9]+]] = keypath $KeyPath, (root $HasDefaultedSubscript; gettable_property $Int, id @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icig : $@convention(method) (Int, HasDefaultedSubscript) -> Int, getter @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipACTK : $@convention(thin) (@in_guaranteed HasDefaultedSubscript, UnsafeRawPointer) -> @out Int, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[DEF_ARG]]) + // CHECK: [[KP:%[0-9]+]] = keypath $KeyPath, (root $HasDefaultedSubscript; gettable_property $Int, id @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icig : $@convention(method) (Int, HasDefaultedSubscript) -> Int, getter @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed HasDefaultedSubscript, @in_guaranteed Int) -> @out Int, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int) ([[DEF_ARG]]) // CHECK: [[SUB_GET:%[0-9]+]] = function_ref @$s29keypath_dynamic_member_lookup8SR_11933V0B6MemberSis7KeyPathCyAA21HasDefaultedSubscriptVSiG_tcig : $@convention(method) (@guaranteed KeyPath, SR_11933) -> Int // CHECK: apply [[SUB_GET]]([[KP]], {{%[0-9]+}}) _ = x[] // CHECK: [[DEF_FN:%[0-9]+]] = function_ref @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipfA_ : $@convention(thin) () -> Int // CHECK: [[DEF_ARG:%[0-9]+]] = apply [[DEF_FN]]() - // CHECK: [[INNER_KP:%[0-9]+]] = keypath $KeyPath, (root $HasDefaultedSubscript; gettable_property $Int, id @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icig : $@convention(method) (Int, HasDefaultedSubscript) -> Int, getter @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipACTK : $@convention(thin) (@in_guaranteed HasDefaultedSubscript, UnsafeRawPointer) -> @out Int, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[DEF_ARG]]) - // CHECK: [[OUTER_KP:%[0-9]+]] = keypath $KeyPath, (root $SR_11933; gettable_property $Int, id @$s29keypath_dynamic_member_lookup8SR_11933V0B6MemberSis7KeyPathCyAA21HasDefaultedSubscriptVSiG_tcig : $@convention(method) (@guaranteed KeyPath, SR_11933) -> Int, getter @$s29keypath_dynamic_member_lookup8SR_11933V0B6MemberSis7KeyPathCyAA21HasDefaultedSubscriptVSiG_tcipACTK : $@convention(thin) (@in_guaranteed SR_11933, UnsafeRawPointer) -> @out Int, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup21HasDefaultedSubscriptVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup21HasDefaultedSubscriptVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[INNER_KP]]) + // CHECK: [[INNER_KP:%[0-9]+]] = keypath $KeyPath, (root $HasDefaultedSubscript; gettable_property $Int, id @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icig : $@convention(method) (Int, HasDefaultedSubscript) -> Int, getter @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed HasDefaultedSubscript, @in_guaranteed Int) -> @out Int, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int) ([[DEF_ARG]]) + // CHECK: [[OUTER_KP:%[0-9]+]] = keypath $KeyPath, (root $SR_11933; gettable_property $Int, id @$s29keypath_dynamic_member_lookup8SR_11933V0B6MemberSis7KeyPathCyAA21HasDefaultedSubscriptVSiG_tcig : $@convention(method) (@guaranteed KeyPath, SR_11933) -> Int, getter @$s29keypath_dynamic_member_lookup8SR_11933V0B6MemberSis7KeyPathCyAA21HasDefaultedSubscriptVSiG_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SR_11933, @in_guaranteed KeyPath) -> @out Int, indices [%$0 : $KeyPath : $KeyPath], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup21HasDefaultedSubscriptVSiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup21HasDefaultedSubscriptVSiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int) ([[INNER_KP]]) _ = \SR_11933.[] } diff --git a/test/DebugInfo/keypath.swift b/test/DebugInfo/keypath.swift index 96df16bbe08e9..95452beff33fb 100644 --- a/test/DebugInfo/keypath.swift +++ b/test/DebugInfo/keypath.swift @@ -8,7 +8,7 @@ public struct Gen { // This used to assert. -// CHECK: distinct !DISubprogram(linkageName: "keypath_set", {{.*}} flags: DIFlagArtificial +// CHECK: distinct !DISubprogram(linkageName: "$sSly7ElementQz5IndexQzcipSMRzSHADRQlxxTK", {{.*}} flags: DIFlagArtificial extension Gen where Value : MutableCollection, Value.Index : Hashable { public var dontAssert: Int { var i = value.startIndex diff --git a/test/IRGen/default_function_ir_attributes.swift b/test/IRGen/default_function_ir_attributes.swift index cf10ccdb9ca9e..930e47451f33f 100644 --- a/test/IRGen/default_function_ir_attributes.swift +++ b/test/IRGen/default_function_ir_attributes.swift @@ -118,14 +118,6 @@ func test_computed_key_path_sil_thunks() -> KeyPath { \S.computed } -// helper function: IR-generated key path getter -// CHECK-LABEL: define {{.*}} swiftcc {{.*}} @keypath_get( -// CHECK-SAME: [[ATTRS_SIMPLE]] - -// helper function: IR-generated key path setter -// CHECK-LABEL: define {{.*}} swiftcc {{.*}} @keypath_set( -// CHECK-SAME: [[ATTRS_SIMPLE]] - // helper function: IR-generated key path arg layout accessor // CHECK-LABEL: define {{.*}} swiftcc {{.*}} @keypath_get_arg_layout( // CHECK-SAME: [[ATTRS_SIMPLE]] @@ -138,14 +130,6 @@ func test_computed_key_path_sil_thunks() -> KeyPath { // CHECK-LABEL: define {{.*}} swiftcc {{.*}} @keypath_copy( // CHECK-SAME: [[ATTRS_SIMPLE]] -// helper function: IR-generated key path equals function -// CHECK-LABEL: define {{.*}} swiftcc {{.*}} @keypath_equals( -// CHECK-SAME: [[ATTRS_SIMPLE]] - -// helper function: IR-generated key path hash function -// CHECK-LABEL: define {{.*}} swiftcc {{.*}} @keypath_hash( -// CHECK-SAME: [[ATTRS_SIMPLE]] - // helper function: IR-generated key path argument initializer // CHECK-LABEL: define {{.*}} swiftcc {{.*}} @keypath_arg_init( // CHECK-SAME: [[ATTRS_SIMPLE]] diff --git a/test/IRGen/keypath_accessor.sil b/test/IRGen/keypath_accessor.sil new file mode 100644 index 0000000000000..830d41a298071 --- /dev/null +++ b/test/IRGen/keypath_accessor.sil @@ -0,0 +1,28 @@ +// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %s + +sil_stage canonical +import Swift + +public struct Blah { + public subscript(x: T) -> T { get } +} + + +sil @$generic_computed_property_indices : $@convention(method) (@in_guaranteed T, Blah) -> @out T + +// CHECK: define {{.*}} swiftcc void @"$generic_computed_property_indices_TK"( +// CHECK-SAME: %swift.opaque* noalias nocapture sret(%swift.opaque) %0, +// CHECK-SAME: %T16keypath_accessor4BlahV* noalias nocapture %1, +// CHECK-SAME: i8* %2, i64 %3) +sil public [thunk] @$generic_computed_property_indices_TK : $@convention(keypath_accessor_getter) (@in_guaranteed Blah, @in_guaranteed T) -> @out T { +bb0(%0 : $*T, %cur_val : $*Blah, %index : $*T): + %3 = load %cur_val : $*Blah + %4 = alloc_stack $T + %5 = function_ref @$generic_computed_property_indices : $@convention(method) <τ_0_0> (@in_guaranteed τ_0_0, Blah) -> @out τ_0_0 + %6 = apply %5(%4, %index, %3) : $@convention(method) <τ_0_0> (@in_guaranteed τ_0_0, Blah) -> @out τ_0_0 + copy_addr [take] %4 to [initialization] %0 : $*T + dealloc_stack %4 : $*T + %7 = tuple () + return %7 : $() +} + diff --git a/test/IRGen/keypaths.sil b/test/IRGen/keypaths.sil index efee4b9078b4b..45559ac47c271 100644 --- a/test/IRGen/keypaths.sil +++ b/test/IRGen/keypaths.sil @@ -172,7 +172,7 @@ sil_vtable C2 {} // -- computed, get-only, identified by (indirected) function pointer, no args // CHECK-SAME: , // CHECK-SAME: @{{got.|"\\01__imp__?}}k_id -// CHECK-SAME: void (%TSi*, %T8keypaths1SV*)* {{.*}}@k_get{{.*}} +// CHECK-SAME: void (%TSi*, %T8keypaths1SV*, i8*, i64)* {{.*}}@k_get{{.*}} // -- %l: computed // CHECK: [[KP_L:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ @@ -184,8 +184,8 @@ sil_vtable C2 {} // -- computed, settable, nonmutating, identified by direct pointer, no args // CHECK-SAME: , // CHECK-SAME: @"$s8keypaths1CCMn" -// CHECK-SAME: void (%TSi*, %T8keypaths1CC**)* @l_get -// CHECK-SAME: void (%TSi*, %T8keypaths1CC**)* @l_set{{.*}} +// CHECK-SAME: void (%TSi*, %T8keypaths1CC**, i8*, i64)* @l_get +// CHECK-SAME: void (%TSi*, %T8keypaths1CC**, i8*, i64)* @l_set{{.*}} // -- %m: computed // CHECK: [[KP_M:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ @@ -197,8 +197,8 @@ sil_vtable C2 {} // -- computed, settable, nonmutating, identified by property offset, no args // CHECK-SAME: , // CHECK-SAME: [[WORD]] -// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* {{.*}}@m_get -// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*)* {{.*}}@m_set{{.*}} +// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*, i8*, i64)* {{.*}}@m_get +// CHECK-SAME: void (%swift.function*, %T8keypaths1SV*, i8*, i64)* {{.*}}@m_set{{.*}} // -- %m2: reabstracted // Note: the contents here aren't interesting. The test triggered infinite @@ -336,10 +336,10 @@ entry: // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_H]] to i8*), i8* undef) %h = keypath $KeyPath, (root $C; stored_property #C.z : $S; stored_property #S.x : $Int) - %k = keypath $KeyPath, (root $S; gettable_property $Int, id @k_id : $@convention(thin) () -> (), getter @k_get : $@convention(thin) (@in_guaranteed S) -> @out Int) - %l = keypath $KeyPath, (root $C; settable_property $Int, id #C.w!getter, getter @l_get : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @l_set : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) - %m = keypath $KeyPath ()>, (root $S; settable_property $() -> (), id ##S.reabstracted, getter @m_get : $@convention(thin) (@in_guaranteed S) -> @out @callee_guaranteed @substituted () -> @out A for <()>, setter @m_set : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout S) -> ()) - %m2 = keypath $KeyPath ()>, (root $C2; settable_property $() -> (), id ##C2.reabstracted, getter @m2_get : $@convention(thin) (@in_guaranteed C2) -> @out @callee_guaranteed @substituted () -> @out A for <()>, setter @m2_set : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout C2) -> ()) + %k = keypath $KeyPath, (root $S; gettable_property $Int, id @k_id : $@convention(thin) () -> (), getter @k_get : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int) + %l = keypath $KeyPath, (root $C; settable_property $Int, id #C.w!getter, getter @l_get : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int, setter @l_set : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> ()) + %m = keypath $KeyPath ()>, (root $S; settable_property $() -> (), id ##S.reabstracted, getter @m_get : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out @callee_guaranteed @substituted () -> @out A for <()>, setter @m_set : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout S) -> ()) + %m2 = keypath $KeyPath ()>, (root $C2; settable_property $() -> (), id ##C2.reabstracted, getter @m2_get : $@convention(keypath_accessor_getter) (@in_guaranteed C2) -> @out @callee_guaranteed @substituted () -> @out A for <()>, setter @m2_set : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout C2) -> ()) // CHECK: call %swift.refcounted* @swift_getKeyPath(i8* bitcast ({{.*}} [[KP_T0]] to i8*), i8* undef) %t0 = keypath $KeyPath, (root $T; stored_property #T.a : $(Int, String); tuple_element #0 : $Int) @@ -351,33 +351,33 @@ entry: } sil @k_id : $@convention(thin) () -> () -sil @k_get : $@convention(thin) (@in_guaranteed S) -> @out Int { +sil @k_get : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int { bb0(%0 : $*Int, %1 : $*S): unreachable } -sil @l_get : $@convention(thin) (@in_guaranteed C) -> @out Int { +sil @l_get : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int { bb0(%0 : $*Int, %1 : $*C): unreachable } -sil @l_set : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> () { +sil @l_set : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> () { bb0(%0 : $*Int, %1 : $*C): unreachable } -sil @m_get : $@convention(thin) (@in_guaranteed S) -> @out @callee_guaranteed @substituted () -> @out A for <()> { +sil @m_get : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out @callee_guaranteed @substituted () -> @out A for <()> { bb0(%0 : $*@callee_guaranteed @substituted () -> @out A for <()>, %1 : $*S): unreachable } -sil @m_set : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout S) -> () { +sil @m_set : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout S) -> () { bb0(%0 : $*@callee_guaranteed @substituted () -> @out A for <()>, %1 : $*S): unreachable } -sil @m2_get : $@convention(thin) (@in_guaranteed C2) -> @out @callee_guaranteed @substituted () -> @out A for <()> -sil @m2_set : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout C2) -> () +sil @m2_get : $@convention(keypath_accessor_getter) (@in_guaranteed C2) -> @out @callee_guaranteed @substituted () -> @out A for <()> +sil @m2_set : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out A for <()>, @inout C2) -> () struct Gen { var x: T @@ -443,103 +443,103 @@ entry: // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @computed_property_generics sil @computed_property_generics : $@convention(thin) () -> () { entry: - %n = keypath $WritableKeyPath, (root $TTT; settable_property $UUU, id @n_get : $@convention(thin) (@in_guaranteed TT) -> @out UU, getter @n_get : $@convention(thin) (@in_guaranteed TT) -> @out UU, setter @n_set : $@convention(thin) (@in_guaranteed UU, @in_guaranteed TT) -> ()) + %n = keypath $WritableKeyPath, (root $TTT; settable_property $UUU, id @n_get : $@convention(keypath_accessor_getter) (@in_guaranteed TT) -> @out UU, getter @n_get : $@convention(keypath_accessor_getter) (@in_guaranteed TT) -> @out UU, setter @n_set : $@convention(keypath_accessor_setter) (@in_guaranteed UU, @in_guaranteed TT) -> ()) return undef : $() } -sil @n_get : $@convention(thin) (@in_guaranteed TT) -> @out UU -sil @n_set : $@convention(thin) (@in_guaranteed UU, @in_guaranteed TT) -> () +sil @n_get : $@convention(keypath_accessor_getter) (@in_guaranteed TT) -> @out UU +sil @n_set : $@convention(keypath_accessor_setter) (@in_guaranteed UU, @in_guaranteed TT) -> () sil @computed_property_indices : $@convention(thin) (C, S, C, S, C, S) -> () { entry(%0 : $C, %1 : $S, %2 : $C, %3 : $S, %4 : $C, %5 : $S): %o = keypath $WritableKeyPath, ( root $S; settable_property $C, - id @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, - getter @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, - setter @o_set : $@convention(thin) (@in_guaranteed C, @in_guaranteed S, UnsafeRawPointer) -> (), + id @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, + getter @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, + setter @o_set : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed S, @in_guaranteed Int) -> (), indices [%$0 : $C : $C], - indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int + indices_equals @o_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @o_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%0) %p = keypath $WritableKeyPath, ( root $S; settable_property $C, - id @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, - getter @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, - setter @o_set : $@convention(thin) (@in_guaranteed C, @in_guaranteed S, UnsafeRawPointer) -> (), + id @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, + getter @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, + setter @o_set : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed S, @in_guaranteed Int) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], - indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int + indices_equals @o_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @o_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%1, %2) %r = keypath $WritableKeyPath, ( root $S; settable_property $C, - id @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, - getter @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C, - setter @o_set : $@convention(thin) (@in_guaranteed C, @in_guaranteed S, UnsafeRawPointer) -> (), + id @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, + getter @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C, + setter @o_set : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed S, @in_guaranteed Int) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], - indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int; + indices_equals @o_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @o_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; settable_property $S, - id @r_get : $@convention(thin) (@in_guaranteed C, UnsafeRawPointer) -> @out S, - getter @r_get : $@convention(thin) (@in_guaranteed C, UnsafeRawPointer) -> @out S, - setter @r_set : $@convention(thin) (@in_guaranteed S, @in_guaranteed C, UnsafeRawPointer) -> (), + id @r_get : $@convention(keypath_accessor_getter) (@in_guaranteed C, @in_guaranteed Int) -> @out S, + getter @r_get : $@convention(keypath_accessor_getter) (@in_guaranteed C, @in_guaranteed Int) -> @out S, + setter @r_set : $@convention(keypath_accessor_setter) (@in_guaranteed S, @in_guaranteed C, @in_guaranteed Int) -> (), indices [%$2 : $S : $S], - indices_equals @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int + indices_equals @o_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @o_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%3, %4, %5) return undef : $() } -sil @o_get : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out C -sil @o_set : $@convention(thin) (@in_guaranteed C, @in_guaranteed S, UnsafeRawPointer) -> () -sil @o_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @o_hash : $@convention(thin) (UnsafeRawPointer) -> Int +sil @o_get : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed Int) -> @out C +sil @o_set : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed S, @in_guaranteed Int) -> () +sil @o_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool +sil @o_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int -sil @r_get : $@convention(thin) (@in_guaranteed C, UnsafeRawPointer) -> @out S -sil @r_set : $@convention(thin) (@in_guaranteed S, @in_guaranteed C, UnsafeRawPointer) -> () +sil @r_get : $@convention(keypath_accessor_getter) (@in_guaranteed C, @in_guaranteed Int) -> @out S +sil @r_set : $@convention(keypath_accessor_setter) (@in_guaranteed S, @in_guaranteed C, @in_guaranteed Int) -> () sil @generic_computed_property_indices : $@convention(thin) (@in_guaranteed A, @in_guaranteed B, @in_guaranteed A, @in_guaranteed B, @in_guaranteed A, @in_guaranteed B) -> () { entry(%0 : $*A, %1 : $*B, %2 : $*A, %3 : $*B, %4 : $*A, %5 : $*B): %s = keypath $WritableKeyPath, ( root $X; settable_property $Y, - id @s_get : $@convention(thin) (@in_guaranteed T, UnsafeRawPointer) -> @out U, - getter @s_get : $@convention(thin) (@in_guaranteed T, UnsafeRawPointer) -> @out U, - setter @s_set : $@convention(thin) (@in_guaranteed U, @in_guaranteed T, UnsafeRawPointer) -> (), + id @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, + getter @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, + setter @s_set : $@convention(keypath_accessor_setter) (@in_guaranteed U, @in_guaranteed T, @in_guaranteed Int) -> (), indices [%$0 : $X : $*X], - indices_equals @s_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @s_hash : $@convention(thin) (UnsafeRawPointer) -> Int + indices_equals @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%0) %t = keypath $WritableKeyPath, ( root $X; settable_property $Y, - id @s_get : $@convention(thin) (@in_guaranteed T, UnsafeRawPointer) -> @out U, - getter @s_get : $@convention(thin) (@in_guaranteed T, UnsafeRawPointer) -> @out U, - setter @s_set : $@convention(thin) (@in_guaranteed U, @in_guaranteed T, UnsafeRawPointer) -> (), + id @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, + getter @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, + setter @s_set : $@convention(keypath_accessor_setter) (@in_guaranteed U, @in_guaranteed T, @in_guaranteed Int) -> (), indices [%$0 : $Y : $*Y, %$1 : $X : $*X], - indices_equals @s_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @s_hash : $@convention(thin) (UnsafeRawPointer) -> Int + indices_equals @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%1, %2) %v = keypath $WritableKeyPath, ( root $X; settable_property $Y, - id @s_get : $@convention(thin) (@in_guaranteed T, UnsafeRawPointer) -> @out U, - getter @s_get : $@convention(thin) (@in_guaranteed T, UnsafeRawPointer) -> @out U, - setter @s_set : $@convention(thin) (@in_guaranteed U, @in_guaranteed T, UnsafeRawPointer) -> (), + id @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, + getter @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed T, @in_guaranteed Int) -> @out U, + setter @s_set : $@convention(keypath_accessor_setter) (@in_guaranteed U, @in_guaranteed T, @in_guaranteed Int) -> (), indices [%$0 : $Y : $*Y, %$1 : $X : $*X], - indices_equals @s_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @s_hash : $@convention(thin) (UnsafeRawPointer) -> Int; + indices_equals @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int; settable_property $X, - id @v_get : $@convention(thin) (@in_guaranteed U, UnsafeRawPointer) -> @out T, - getter @v_get : $@convention(thin) (@in_guaranteed U, UnsafeRawPointer) -> @out T, - setter @v_set : $@convention(thin) (@in_guaranteed T, @in_guaranteed U, UnsafeRawPointer) -> (), + id @v_get : $@convention(keypath_accessor_getter) (@in_guaranteed U, @in_guaranteed Int) -> @out T, + getter @v_get : $@convention(keypath_accessor_getter) (@in_guaranteed U, @in_guaranteed Int) -> @out T, + setter @v_set : $@convention(keypath_accessor_setter) (@in_guaranteed T, @in_guaranteed U, @in_guaranteed Int) -> (), indices [%$2 : $Y : $*Y], - indices_equals @s_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @s_hash : $@convention(thin) (UnsafeRawPointer) -> Int + indices_equals @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int ) (%3, %4, %5) return undef : $() @@ -572,10 +572,10 @@ bb0: return %t : $() } -sil @s_get : $@convention(thin) (@in_guaranteed A, UnsafeRawPointer) -> @out B -sil @s_set : $@convention(thin) (@in_guaranteed B, @in_guaranteed A, UnsafeRawPointer) -> () -sil @s_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @s_hash : $@convention(thin) (UnsafeRawPointer) -> Int +sil @s_get : $@convention(keypath_accessor_getter) (@in_guaranteed A, @in_guaranteed Int) -> @out B +sil @s_set : $@convention(keypath_accessor_setter) (@in_guaranteed B, @in_guaranteed A, @in_guaranteed Int) -> () +sil @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool +sil @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int -sil @v_get : $@convention(thin) (@in_guaranteed B, UnsafeRawPointer) -> @out A -sil @v_set : $@convention(thin) (@in_guaranteed A, @in_guaranteed B, UnsafeRawPointer) -> () +sil @v_get : $@convention(keypath_accessor_getter) (@in_guaranteed B, @in_guaranteed Int) -> @out A +sil @v_set : $@convention(keypath_accessor_setter) (@in_guaranteed A, @in_guaranteed B, @in_guaranteed Int) -> () diff --git a/test/IRGen/keypaths_external.sil b/test/IRGen/keypaths_external.sil index 333edc8d458dd..582efefd0699f 100644 --- a/test/IRGen/keypaths_external.sil +++ b/test/IRGen/keypaths_external.sil @@ -14,31 +14,31 @@ entry(%0 : $*A, %1 : $*B, %2 : $*A, %3 : $*B, %4 : $*A, %5 : $*B): %t = keypath $KeyPath, B>, ( root $G; gettable_property $Z, - id @g_x_get : $@convention(thin) (@in_guaranteed G) -> @out Z, - getter @g_x_get : $@convention(thin) (@in_guaranteed G) -> @out Z, + id @g_x_get : $@convention(keypath_accessor_getter) (@in_guaranteed G) -> @out Z, + getter @g_x_get : $@convention(keypath_accessor_getter) (@in_guaranteed G) -> @out Z, external #G.x ) %u = keypath $KeyPath, A>, ( root $G; gettable_property $Y, - id @g_subscript_get : $@convention(thin) (@in_guaranteed G, UnsafeRawPointer) -> @out B, - getter @g_subscript_get : $@convention(thin) (@in_guaranteed G, UnsafeRawPointer) -> @out B, + id @g_subscript_get : $@convention(keypath_accessor_getter) (@in_guaranteed G, @in_guaranteed Int) -> @out B, + getter @g_subscript_get : $@convention(keypath_accessor_getter) (@in_guaranteed G, @in_guaranteed Int) -> @out B, indices [%$0 : $X : $*X], - indices_equals @s_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, - indices_hash @s_hash : $@convention(thin) (UnsafeRawPointer) -> Int, + indices_equals @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, + indices_hash @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int, external #G.subscript ) (%1) return undef : $() } -sil @g_x_get : $@convention(thin) (@in_guaranteed G) -> @out Z -sil @g_subscript_get : $@convention(thin) (@in_guaranteed G, UnsafeRawPointer) -> +sil @g_x_get : $@convention(keypath_accessor_getter) (@in_guaranteed G) -> @out Z +sil @g_subscript_get : $@convention(keypath_accessor_getter) (@in_guaranteed G, @in_guaranteed Int) -> @out B -sil @s_equals : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @s_hash : $@convention(thin) (UnsafeRawPointer) -> Int +sil @s_equals : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool +sil @s_hash : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int // -- %t // CHECK: [[KP_T:@keypath(\..*)?]] = private global <{ {{.*}} }> <{ {{.*}} i32 1, {{.*}} @"{{got.|\\01__imp__?}}$s23keypaths_external_other1GV1xxvpMV" diff --git a/test/IRGen/property_descriptor.sil b/test/IRGen/property_descriptor.sil index 7da3ce2abacba..350c1eca9de3c 100644 --- a/test/IRGen/property_descriptor.sil +++ b/test/IRGen/property_descriptor.sil @@ -63,7 +63,7 @@ sil_property #ExternalGeneric.rw ( sil_property #ExternalGeneric.computedRO ( gettable_property $T, id @id_computed : $@convention(thin) () -> (), - getter @get_computed_generic : $@convention(thin) (@in_guaranteed ExternalGeneric) -> @out T) + getter @get_computed_generic : $@convention(keypath_accessor_getter) (@in_guaranteed ExternalGeneric) -> @out T) // CHECK: @"$s19property_descriptor15ExternalGenericV10computedRWxvpMV" = // -- 0x01c8_0000 - computed, settable, mutating, has arguments, indirect id @@ -77,8 +77,8 @@ sil_property #ExternalGeneric.computedRO ( sil_property #ExternalGeneric.computedRW ( settable_property $T, id @id_computed : $@convention(thin) () -> (), - getter @get_computed_generic : $@convention(thin) (@in_guaranteed ExternalGeneric) -> @out T, - setter @set_computed_generic : $@convention(thin) (@in_guaranteed T, @inout ExternalGeneric) -> ()) + getter @get_computed_generic : $@convention(keypath_accessor_getter) (@in_guaranteed ExternalGeneric) -> @out T, + setter @set_computed_generic : $@convention(keypath_accessor_setter) (@in_guaranteed T, @inout ExternalGeneric) -> ()) // CHECK: @"$s19property_descriptor15ExternalGenericVyxqd__cSHRd__luipMV" = // -- 0x01c8_0000 - computed, settable, mutating, has arguments, indirect id @@ -92,8 +92,8 @@ sil_property #ExternalGeneric.computedRW ( sil_property #ExternalGeneric.subscript ( settable_property $T, id @id_computed : $@convention(thin) () -> (), - getter @get_computed_generic_subscript : $@convention(thin) (@in_guaranteed ExternalGeneric, UnsafeRawPointer) -> @out T, - setter @set_computed_generic_subscript : $@convention(thin) (@in_guaranteed T, @inout ExternalGeneric, UnsafeRawPointer) -> ()) + getter @get_computed_generic_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed ExternalGeneric, @in_guaranteed U) -> @out T, + setter @set_computed_generic_subscript : $@convention(keypath_accessor_setter) (@in_guaranteed T, @inout ExternalGeneric, @in_guaranteed U) -> ()) // CHECK: @"$s19property_descriptor8ExternalV2roSivpMV" = // CHECK-64: @"$s19property_descriptor8ExternalV2rwSivpMV" = @@ -103,17 +103,17 @@ sil_property #External.rw (stored_property #External.rw : $Int) sil_property #External.computedRO ( gettable_property $Int, id @id_computed : $@convention(thin) () -> (), - getter @get_computed : $@convention(thin) (@in_guaranteed External) -> @out Int) + getter @get_computed : $@convention(keypath_accessor_getter) (@in_guaranteed External) -> @out Int) sil_property #External.computedRW ( settable_property $Int, id @id_computed : $@convention(thin) () -> (), - getter @get_computed : $@convention(thin) (@in_guaranteed External) -> @out Int, - setter @set_computed : $@convention(thin) (@in_guaranteed Int, @inout External) -> ()) + getter @get_computed : $@convention(keypath_accessor_getter) (@in_guaranteed External) -> @out Int, + setter @set_computed : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout External) -> ()) sil_property #External.subscript ( settable_property $Int, id @id_computed : $@convention(thin) () -> (), - getter @get_computed_subscript : $@convention(thin) (@in_guaranteed External, UnsafeRawPointer) -> @out Int, - setter @set_computed_subscript : $@convention(thin) (@in_guaranteed Int, @inout External, UnsafeRawPointer) -> ()) + getter @get_computed_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed External, @in_guaranteed String) -> @out Int, + setter @set_computed_subscript : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout External, @in_guaranteed String) -> ()) sil_property #ExternalReabstractions.ro ( stored_property #ExternalReabstractions.ro : $T) @@ -121,8 +121,8 @@ sil_property #ExternalReabstractions.ro ( sil_property #ExternalReabstractions.reabstracted ( settable_property $() -> (), id ##ExternalReabstractions.reabstracted, - getter @get_reabstracted : $@convention(thin) (@in_guaranteed ExternalReabstractions) -> @out @callee_guaranteed @substituted () -> @out U for <()>, - setter @set_reabstracted : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out U for <()>, @inout ExternalReabstractions) -> ()) + getter @get_reabstracted : $@convention(keypath_accessor_getter) (@in_guaranteed ExternalReabstractions) -> @out @callee_guaranteed @substituted () -> @out U for <()>, + setter @set_reabstracted : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out U for <()>, @inout ExternalReabstractions) -> ()) // All trivial descriptors should share a definition by aliasing to the common // definition @@ -136,17 +136,17 @@ sil_property #ExternalGeneric.computedWithTrivialDescriptor () sil_property #External.computedWithTrivialDescriptor () sil @id_computed : $@convention(thin) () -> () -sil @get_computed : $@convention(thin) (@in_guaranteed External) -> @out Int -sil @set_computed : $@convention(thin) (@in_guaranteed Int, @inout External) -> () +sil @get_computed : $@convention(keypath_accessor_getter) (@in_guaranteed External) -> @out Int +sil @set_computed : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout External) -> () -sil @get_computed_subscript : $@convention(thin) (@in_guaranteed External, UnsafeRawPointer) -> @out Int -sil @set_computed_subscript : $@convention(thin) (@in_guaranteed Int, @inout External, UnsafeRawPointer) -> () +sil @get_computed_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed External, @in_guaranteed String) -> @out Int +sil @set_computed_subscript : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout External, @in_guaranteed String) -> () -sil @get_computed_generic : $@convention(thin) (@in_guaranteed ExternalGeneric) -> @out T -sil @set_computed_generic : $@convention(thin) (@in_guaranteed T, @inout ExternalGeneric) -> () +sil @get_computed_generic : $@convention(keypath_accessor_getter) (@in_guaranteed ExternalGeneric) -> @out T +sil @set_computed_generic : $@convention(keypath_accessor_setter) (@in_guaranteed T, @inout ExternalGeneric) -> () -sil @get_computed_generic_subscript : $@convention(thin) (@in_guaranteed ExternalGeneric, UnsafeRawPointer) -> @out T -sil @set_computed_generic_subscript : $@convention(thin) (@in_guaranteed T, @inout ExternalGeneric, UnsafeRawPointer) -> () +sil @get_computed_generic_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed ExternalGeneric, @in_guaranteed U) -> @out T +sil @set_computed_generic_subscript : $@convention(keypath_accessor_setter) (@in_guaranteed T, @inout ExternalGeneric, @in_guaranteed U) -> () -sil @get_reabstracted : $@convention(thin) (@in_guaranteed ExternalReabstractions) -> @out @callee_guaranteed @substituted () -> @out U for <()> -sil @set_reabstracted : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted () -> @out U for <()>, @inout ExternalReabstractions) -> () +sil @get_reabstracted : $@convention(keypath_accessor_getter) (@in_guaranteed ExternalReabstractions) -> @out @callee_guaranteed @substituted () -> @out U for <()> +sil @set_reabstracted : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted () -> @out U for <()>, @inout ExternalReabstractions) -> () diff --git a/test/SIL/Parser/keypath.sil b/test/SIL/Parser/keypath.sil index 651815a23eb25..33e840eb3717e 100644 --- a/test/SIL/Parser/keypath.sil +++ b/test/SIL/Parser/keypath.sil @@ -92,50 +92,50 @@ entry: } sil @id_a : $@convention(thin) () -> () -sil @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int -sil @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> () -sil @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int -sil @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> () -sil @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> @out @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for -sil @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , @in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> () -sil @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int -sil @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> () -sil @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int -sil @get_gen_int_subs : $@convention(thin) (@in_guaranteed A, UnsafeRawPointer) -> @out C -sil @set_gen_int_subs : $@convention(thin) (@in_guaranteed C, @in_guaranteed A, UnsafeRawPointer) -> () -sil @gen_subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @gen_subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int +sil @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int +sil @set_s_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S) -> () +sil @get_c_int : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int +sil @set_c_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> () +sil @get_fns_fnc : $@convention(keypath_accessor_getter) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> @out @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for +sil @set_fns_fnc : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , @in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> () +sil @get_s_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed (S, C)) -> @out Int +sil @set_s_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S, @in_guaranteed (S, C)) -> () +sil @subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool +sil @subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int +sil @get_gen_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed A, @in_guaranteed (S, C)) -> @out C +sil @set_gen_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed A, @in_guaranteed (S, C)) -> () +sil @gen_subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool +sil @gen_subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int // CHECK-LABEL: sil shared @computed_properties sil shared @computed_properties : $@convention(thin) () -> () { entry: - // CHECK: keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int) - %a = keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int) - // CHECK: keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> ()) - %b = keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> ()) - // CHECK: keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) + // CHECK: keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int) + %a = keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int) + // CHECK: keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S) -> ()) + %b = keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S) -> ()) + // CHECK: keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(keypath_accessor_getter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) %c = keypath $WritableKeyPath<(S) -> S, (C) -> C>, ( root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), - getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> @out @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , - setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , @in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> ()) - // CHECK: keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) - %d = keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) + getter @get_fns_fnc : $@convention(keypath_accessor_getter) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> @out @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , + setter @set_fns_fnc : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for , @in_guaranteed @callee_guaranteed @substituted (@in_guaranteed A) -> @out B for ) -> ()) + // CHECK: keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> ()) + %d = keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> ()) return undef : $() } -sil @get_gen_a : $@convention(thin) (@in_guaranteed Gen) -> @out X1 -sil @set_gen_a : $@convention(thin) (@in_guaranteed X2, @in_guaranteed Gen) -> () +sil @get_gen_a : $@convention(keypath_accessor_getter) (@in_guaranteed Gen) -> @out X1 +sil @set_gen_a : $@convention(keypath_accessor_setter) (@in_guaranteed X2, @in_guaranteed Gen) -> () // CHECK-LABEL: sil shared @computed_properties_generic sil shared @computed_properties_generic : $@convention(thin) () -> () { entry: - // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> ()) - %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(thin) (@in_guaranteed X4, @in_guaranteed Gen) -> ()) + // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(keypath_accessor_setter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> ()) + %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(keypath_accessor_setter) (@in_guaranteed X4, @in_guaranteed Gen) -> ()) return undef : $() } @@ -166,14 +166,14 @@ entry: sil @indexes : $@convention(thin) (S, C) -> () { // CHECK: bb0([[S:%.*]] : $S, [[C:%.*]] : $C): entry(%s : $S, %c : $C): - // CHECK: keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int, setter @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) ([[S]], [[C]]) - %a = keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int, setter @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) (%s, %c) + // CHECK: keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed (S, C)) -> @out Int, setter @set_s_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S, @in_guaranteed (S, C)) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool, indices_hash @subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int) ([[S]], [[C]]) + %a = keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed (S, C)) -> @out Int, setter @set_s_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S, @in_guaranteed (S, C)) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool, indices_hash @subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int) (%s, %c) // CHECK: [[T:%.*]] = alloc_stack %t = alloc_stack $S // CHECK: [[D:%.*]] = alloc_stack %d = alloc_stack $C - // CHECK: keypath $KeyPath, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (root $τ_0_0; settable_property $τ_0_2, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_0, UnsafeRawPointer) -> @out τ_0_2, setter @set_gen_int_subs : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_2, @in_guaranteed τ_0_0, UnsafeRawPointer) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $τ_0_1 : $*τ_0_1], indices_equals @gen_subs_eq : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @gen_subs_hash : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (UnsafeRawPointer) -> Int) ([[T]], [[D]]) - %b = keypath $KeyPath, <τ_0_0: Hashable, Y: Hashable, Z: Hashable> (root $τ_0_0; settable_property $Z, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(thin) (@in_guaranteed A, UnsafeRawPointer) -> @out C, setter @set_gen_int_subs : $@convention(thin) (@in_guaranteed C, @in_guaranteed A, UnsafeRawPointer) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $Y : $*Y], indices_equals @gen_subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @gen_subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) (%t, %d) + // CHECK: keypath $KeyPath, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (root $τ_0_0; settable_property $τ_0_2, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_0, @in_guaranteed (S, τ_0_2)) -> @out τ_0_2, setter @set_gen_int_subs : $@convention(keypath_accessor_setter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_2, @in_guaranteed τ_0_0, @in_guaranteed (S, τ_0_2)) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $τ_0_1 : $*τ_0_1], indices_equals @gen_subs_eq : $@convention(keypath_accessor_equals) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed (S, τ_0_2), @in_guaranteed (S, τ_0_2)) -> Bool, indices_hash @gen_subs_hash : $@convention(keypath_accessor_hash) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed (S, τ_0_2)) -> Int) ([[T]], [[D]]) + %b = keypath $KeyPath, <τ_0_0: Hashable, Y: Hashable, Z: Hashable> (root $τ_0_0; settable_property $Z, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed A, @in_guaranteed (S, C)) -> @out C, setter @set_gen_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed A, @in_guaranteed (S, C)) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $Y : $*Y], indices_equals @gen_subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool, indices_hash @gen_subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int) (%t, %d) dealloc_stack %d : $*C dealloc_stack %t : $*S @@ -184,22 +184,22 @@ entry(%s : $S, %c : $C): // CHECK-LABEL: sil @external sil @external : $@convention(thin) () -> () { entry: - // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> (), external #Gen.x<τ_0_0, τ_0_1, τ_0_2>) - %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(thin) (@in_guaranteed X4, @in_guaranteed Gen) -> (), external #Gen.x) + // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(keypath_accessor_setter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> (), external #Gen.x<τ_0_0, τ_0_1, τ_0_2>) + %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(keypath_accessor_setter) (@in_guaranteed X4, @in_guaranteed Gen) -> (), external #Gen.x) return undef : $() } -sil @get_external_subscript : $@convention(thin) (@in_guaranteed External, UnsafeRawPointer) -> @out T -sil @equals_external_subscript : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @hash_external_subscript : $@convention(thin) (UnsafeRawPointer) -> Int +sil @get_external_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed External, @in_guaranteed U) -> @out T +sil @equals_external_subscript : $@convention(keypath_accessor_equals) (@in_guaranteed U, @in_guaranteed U) -> Bool +sil @hash_external_subscript : $@convention(keypath_accessor_hash) (@in_guaranteed U) -> Int // CHECK-LABEL: sil_property #External.ro<τ_0_0> (stored_property #External.ro : $τ_0_0) sil_property #External.ro (stored_property #External.ro : $T) // CHECK-LABEL: sil_property #External.subscript<τ_0_0><τ_1_0 where τ_1_0 : Hashable> (gettable_property $τ_0_0, // CHECK-SAME: id @id_a : $@convention(thin) () -> (), -// CHECK-SAME: getter @get_external_subscript : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (@in_guaranteed External<τ_0_0>, UnsafeRawPointer) -> @out τ_0_0) +// CHECK-SAME: getter @get_external_subscript : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (@in_guaranteed External<τ_0_0>, @in_guaranteed τ_0_1) -> @out τ_0_0 sil_property #External.subscript (gettable_property $T, id @id_a : $@convention(thin) () -> (), - getter @get_external_subscript : $@convention(thin) (@in_guaranteed External, UnsafeRawPointer) -> @out T) + getter @get_external_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed External, @in_guaranteed U) -> @out T) diff --git a/test/SIL/Serialization/keypath.sil b/test/SIL/Serialization/keypath.sil index dbf0242f94e53..810c507a71cc2 100644 --- a/test/SIL/Serialization/keypath.sil +++ b/test/SIL/Serialization/keypath.sil @@ -131,44 +131,44 @@ entry: } sil @id_a : $@convention(thin) () -> () -sil @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int -sil @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> () -sil @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int -sil @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> () -sil @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for -sil @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () -sil @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int -sil @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> () -sil @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int -sil @get_gen_int_subs : $@convention(thin) (@in_guaranteed A, UnsafeRawPointer) -> @out C -sil @set_gen_int_subs : $@convention(thin) (@in_guaranteed C, @in_guaranteed A, UnsafeRawPointer) -> () -sil @gen_subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @gen_subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int +sil @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int +sil @set_s_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S) -> () +sil @get_c_int : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int +sil @set_c_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> () +sil @get_fns_fnc : $@convention(keypath_accessor_getter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for +sil @set_fns_fnc : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> () +sil @get_s_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed (S, C)) -> @out Int +sil @set_s_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S, @in_guaranteed (S, C)) -> () +sil @subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool +sil @subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int +sil @get_gen_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed A, @in_guaranteed (S, C)) -> @out C +sil @set_gen_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed A, @in_guaranteed (S, C)) -> () +sil @gen_subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool +sil @gen_subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int // CHECK-LABEL: sil shared [serialized] @EE_computed_properties sil shared [serialized] @EE_computed_properties : $@convention(thin) () -> () { entry: - // CHECK: keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int) - %a = keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int) - // CHECK: keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> ()) - %b = keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(thin) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S) -> ()) - // CHECK: keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) - %c = keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) - // CHECK: keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) - %d = keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) + // CHECK: keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int) + %a = keypath $KeyPath, (root $S; gettable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int) + // CHECK: keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S) -> ()) + %b = keypath $WritableKeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int : $@convention(keypath_accessor_getter) (@in_guaranteed S) -> @out Int, setter @set_s_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S) -> ()) + // CHECK: keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(keypath_accessor_getter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) + %c = keypath $WritableKeyPath<(S) -> S, (C) -> C>, (root $(S) -> S; settable_property $(C) -> C, id @id_a : $@convention(thin) () -> (), getter @get_fns_fnc : $@convention(keypath_accessor_getter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , setter @set_fns_fnc : $@convention(keypath_accessor_setter) (@in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @in_guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> ()) + // CHECK: keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> ()) + %d = keypath $WritableKeyPath, (root $C; settable_property $Int, id #C.overridable!getter : (C) -> () -> Int, getter @get_c_int : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int, setter @set_c_int : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> ()) return undef : $() } -sil @get_gen_a : $@convention(thin) (@in_guaranteed Gen) -> @out X1 -sil @set_gen_a : $@convention(thin) (@in_guaranteed X2, @in_guaranteed Gen) -> () +sil @get_gen_a : $@convention(keypath_accessor_getter) (@in_guaranteed Gen) -> @out X1 +sil @set_gen_a : $@convention(keypath_accessor_setter) (@in_guaranteed X2, @in_guaranteed Gen) -> () // CHECK-LABEL: sil shared [serialized] @FF_computed_properties_generic sil shared [serialized] @FF_computed_properties_generic : $@convention(thin) () -> () { entry: - // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> ()) - %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(thin) (@in_guaranteed X4, @in_guaranteed Gen) -> ()) + // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(keypath_accessor_setter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> ()) + %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(keypath_accessor_setter) (@in_guaranteed X4, @in_guaranteed Gen) -> ()) return undef : $() } @@ -188,14 +188,14 @@ entry: sil shared [serialized] @HH_indexes : $@convention(thin) (S, C) -> () { // CHECK: bb0([[S:%.*]] : $S, [[C:%.*]] : $C): entry(%s : $S, %c : $C): - // CHECK: keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int, setter @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) ([[S]], [[C]]) - %a = keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(thin) (@in_guaranteed S, UnsafeRawPointer) -> @out Int, setter @set_s_int_subs : $@convention(thin) (@in_guaranteed Int, @in_guaranteed S, UnsafeRawPointer) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) (%s, %c) + // CHECK: keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed (S, C)) -> @out Int, setter @set_s_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S, @in_guaranteed (S, C)) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool, indices_hash @subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int) ([[S]], [[C]]) + %a = keypath $KeyPath, (root $S; settable_property $Int, id @id_a : $@convention(thin) () -> (), getter @get_s_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed S, @in_guaranteed (S, C)) -> @out Int, setter @set_s_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed S, @in_guaranteed (S, C)) -> (), indices [%$0 : $S : $S, %$1 : $C : $C], indices_equals @subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool, indices_hash @subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int) (%s, %c) // CHECK: [[T:%.*]] = alloc_stack %t = alloc_stack $S // CHECK: [[D:%.*]] = alloc_stack %d = alloc_stack $C - // CHECK: keypath $KeyPath, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (root $τ_0_0; settable_property $τ_0_2, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_0, UnsafeRawPointer) -> @out τ_0_2, setter @set_gen_int_subs : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_2, @in_guaranteed τ_0_0, UnsafeRawPointer) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $τ_0_1 : $*τ_0_1], indices_equals @gen_subs_eq : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @gen_subs_hash : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (UnsafeRawPointer) -> Int) ([[T]], [[D]]) - %b = keypath $KeyPath, <τ_0_0: Hashable, Y: Hashable, Z: Hashable> (root $τ_0_0; settable_property $Z, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(thin) (@in_guaranteed A, UnsafeRawPointer) -> @out C, setter @set_gen_int_subs : $@convention(thin) (@in_guaranteed C, @in_guaranteed A, UnsafeRawPointer) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $Y : $*Y], indices_equals @gen_subs_eq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @gen_subs_hash : $@convention(thin) (UnsafeRawPointer) -> Int) (%t, %d) + // CHECK: keypath $KeyPath, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (root $τ_0_0; settable_property $τ_0_2, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_0, @in_guaranteed (S, τ_0_2)) -> @out τ_0_2, setter @set_gen_int_subs : $@convention(keypath_accessor_setter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed τ_0_2, @in_guaranteed τ_0_0, @in_guaranteed (S, τ_0_2)) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $τ_0_1 : $*τ_0_1], indices_equals @gen_subs_eq : $@convention(keypath_accessor_equals) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed (S, τ_0_2), @in_guaranteed (S, τ_0_2)) -> Bool, indices_hash @gen_subs_hash : $@convention(keypath_accessor_hash) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : Hashable, τ_0_1 : Hashable, τ_0_2 : Hashable> (@in_guaranteed (S, τ_0_2)) -> Int) ([[T]], [[D]]) + %b = keypath $KeyPath, <τ_0_0: Hashable, Y: Hashable, Z: Hashable> (root $τ_0_0; settable_property $Z, id @id_a : $@convention(thin) () -> (), getter @get_gen_int_subs : $@convention(keypath_accessor_getter) (@in_guaranteed A, @in_guaranteed (S, C)) -> @out C, setter @set_gen_int_subs : $@convention(keypath_accessor_setter) (@in_guaranteed C, @in_guaranteed A, @in_guaranteed (S, C)) -> (), indices [%$0 : $τ_0_0 : $*τ_0_0, %$1 : $Y : $*Y], indices_equals @gen_subs_eq : $@convention(keypath_accessor_equals) (@in_guaranteed (S, C), @in_guaranteed (S, C)) -> Bool, indices_hash @gen_subs_hash : $@convention(keypath_accessor_hash) (@in_guaranteed (S, C)) -> Int) (%t, %d) dealloc_stack %d : $*C dealloc_stack %t : $*S @@ -206,8 +206,8 @@ entry(%s : $S, %c : $C): // CHECK-LABEL: sil shared [serialized] @II_external sil shared [serialized] @II_external : $@convention(thin) () -> () { entry: - // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(thin) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> (), external #Gen.x<τ_0_0, τ_0_1, τ_0_2>) - %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(thin) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(thin) (@in_guaranteed X4, @in_guaranteed Gen) -> (), external #Gen.x) + // CHECK: keypath $KeyPath, D>, <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (root $Gen<τ_0_0, τ_0_1, τ_0_2>; settable_property $τ_0_0, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> @out τ_0_0, setter @set_gen_a : $@convention(keypath_accessor_setter) <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : P, τ_0_1 : Q, τ_0_2 : R> (@in_guaranteed τ_0_0, @in_guaranteed Gen<τ_0_0, τ_0_1, τ_0_2>) -> (), external #Gen.x<τ_0_0, τ_0_1, τ_0_2>) + %a = keypath $KeyPath, D>, (root $Gen; settable_property $G, id @id_a : $@convention(thin) () -> (), getter @get_gen_a : $@convention(keypath_accessor_getter) (@in_guaranteed Gen) -> @out X3, setter @set_gen_a : $@convention(keypath_accessor_setter) (@in_guaranteed X4, @in_guaranteed Gen) -> (), external #Gen.x) return undef : $() } @@ -227,16 +227,16 @@ entry: unreachable } -sil [serialized] @get_external_subscript : $@convention(thin) (@in_guaranteed External, UnsafeRawPointer) -> @out T -sil [serialized] @equals_external_subscript : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil [serialized] @hash_external_subscript : $@convention(thin) (UnsafeRawPointer) -> Int +sil [serialized] @get_external_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed External, @in_guaranteed U) -> @out T +sil [serialized] @equals_external_subscript : $@convention(keypath_accessor_equals) (@in_guaranteed U, @in_guaranteed U) -> Bool +sil [serialized] @hash_external_subscript : $@convention(keypath_accessor_hash) (@in_guaranteed U) -> Int // CHECK-LABEL: sil_property [serialized] #External.ro<τ_0_0> (stored_property #External.ro : $τ_0_0) sil_property [serialized] #External.ro (stored_property #External.ro : $T) // CHECK-LABEL: sil_property [serialized] #External.subscript<τ_0_0><τ_1_0 where τ_1_0 : Hashable> (gettable_property $τ_0_0, // CHECK-SAME: id @id_a : $@convention(thin) () -> (), -// CHECK-SAME: getter @get_external_subscript : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (@in_guaranteed External<τ_0_0>, UnsafeRawPointer) -> @out τ_0_0) +// CHECK-SAME: getter @get_external_subscript : $@convention(keypath_accessor_getter) <τ_0_0, τ_0_1 where τ_0_1 : Hashable> (@in_guaranteed External<τ_0_0>, @in_guaranteed τ_0_1) -> @out τ_0_0) sil_property [serialized] #External.subscript (gettable_property $T, id @id_a : $@convention(thin) () -> (), - getter @get_external_subscript : $@convention(thin) (@in_guaranteed External, UnsafeRawPointer) -> @out T) + getter @get_external_subscript : $@convention(keypath_accessor_getter) (@in_guaranteed External, @in_guaranteed U) -> @out T) diff --git a/test/SILGen/default_arg_multiple_modules.swift b/test/SILGen/default_arg_multiple_modules.swift index 7a13494c6ef15..2897faf833edd 100644 --- a/test/SILGen/default_arg_multiple_modules.swift +++ b/test/SILGen/default_arg_multiple_modules.swift @@ -39,7 +39,7 @@ func test3() -> String { func test4() { // CHECK: [[DEF_ARG_FN:%[0-9]+]] = function_ref @$s17default_arg_other10Subscript1VyS2icipfA_ : $@convention(thin) () -> Int // CHECK: [[DEF_ARG:%[0-9]+]] = apply [[DEF_ARG_FN]]() {{.*}} - // CHECK: keypath $KeyPath, (root $Subscript1; gettable_property $Int, id @$s17default_arg_other10Subscript1VyS2icig : $@convention(method) (Int, Subscript1) -> Int, getter @$s17default_arg_other10Subscript1VyS2icipACTK : $@convention(thin) (@in_guaranteed Subscript1, UnsafeRawPointer) -> @out Int, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int, external #Subscript1.subscript) ([[DEF_ARG]]) + // CHECK: keypath $KeyPath, (root $Subscript1; gettable_property $Int, id @$s17default_arg_other10Subscript1VyS2icig : $@convention(method) (Int, Subscript1) -> Int, getter @$s17default_arg_other10Subscript1VyS2icipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed Subscript1, @in_guaranteed Int) -> @out Int, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(keypath_accessor_equals) (@in_guaranteed Int, @in_guaranteed Int) -> Bool, indices_hash @$sSiTh : $@convention(keypath_accessor_hash) (@in_guaranteed Int) -> Int, external #Subscript1.subscript) ([[DEF_ARG]]) _ = \Subscript1.[] } @@ -48,6 +48,6 @@ func test5() { // This should not call default arg constructor // CHECK: [[STR_LIT:%[0-9]+]] = string_literal utf8 "test5()" // CHECK: [[DEF_ARG:%[0-9]+]] = apply %{{[0-9]+}}([[STR_LIT]], {{.*}} - // CHECK: keypath $KeyPath, (root $Subscript2; gettable_property $String, id @$s17default_arg_other10Subscript2VyS2Scig : $@convention(method) (@guaranteed String, Subscript2) -> @owned String, getter @$s17default_arg_other10Subscript2VyS2ScipACTK : $@convention(thin) (@in_guaranteed Subscript2, UnsafeRawPointer) -> @out String, indices [%$0 : $String : $String], indices_equals @$sSSTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSSTh : $@convention(thin) (UnsafeRawPointer) -> Int, external #Subscript2.subscript) ([[DEF_ARG]]) + // CHECK: keypath $KeyPath, (root $Subscript2; gettable_property $String, id @$s17default_arg_other10Subscript2VyS2Scig : $@convention(method) (@guaranteed String, Subscript2) -> @owned String, getter @$s17default_arg_other10Subscript2VyS2ScipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed Subscript2, @in_guaranteed String) -> @out String, indices [%$0 : $String : $String], indices_equals @$sSSTH : $@convention(keypath_accessor_equals) (@in_guaranteed String, @in_guaranteed String) -> Bool, indices_hash @$sSSTh : $@convention(keypath_accessor_hash) (@in_guaranteed String) -> Int, external #Subscript2.subscript) ([[DEF_ARG]]) _ = \Subscript2.[] } diff --git a/test/SILGen/keypaths.swift b/test/SILGen/keypaths.swift index b750becd98b9c..7833bf38be4ee 100644 --- a/test/SILGen/keypaths.swift +++ b/test/SILGen/keypaths.swift @@ -78,8 +78,8 @@ func computedProperties(_: T) { // CHECK-SAME: root $C<τ_0_0>; // CHECK-SAME: settable_property $S<τ_0_0>, // CHECK-SAME: id #C.nonfinal!getter : (C) -> () -> S, - // CHECK-SAME: getter @$s8keypaths1CC8nonfinalAA1SVyxGvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out S<τ_0_0>, - // CHECK-SAME: setter @$s8keypaths1CC8nonfinalAA1SVyxGvpAA1PRzlACyxGTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>, @in_guaranteed C<τ_0_0>) -> () + // CHECK-SAME: getter @$s8keypaths1CC8nonfinalAA1SVyxGvpAA1PRzlACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out S<τ_0_0>, + // CHECK-SAME: setter @$s8keypaths1CC8nonfinalAA1SVyxGvpAA1PRzlACyxGTk : $@convention(keypath_accessor_setter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>, @in_guaranteed C<τ_0_0>) -> () // CHECK-SAME: ) _ = \C.nonfinal @@ -87,7 +87,7 @@ func computedProperties(_: T) { // CHECK-SAME: root $C<τ_0_0>; // CHECK-SAME: gettable_property $S<τ_0_0>, // CHECK-SAME: id #C.computed!getter : (C) -> () -> S, - // CHECK-SAME: getter @$s8keypaths1CC8computedAA1SVyxGvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out S<τ_0_0> + // CHECK-SAME: getter @$s8keypaths1CC8computedAA1SVyxGvpAA1PRzlACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out S<τ_0_0> // CHECK-SAME: ) _ = \C.computed @@ -95,8 +95,8 @@ func computedProperties(_: T) { // CHECK-SAME: root $C<τ_0_0>; // CHECK-SAME: settable_property $S<τ_0_0>, // CHECK-SAME: id #C.observed!getter : (C) -> () -> S, - // CHECK-SAME: getter @$s8keypaths1CC8observedAA1SVyxGvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out S<τ_0_0>, - // CHECK-SAME: setter @$s8keypaths1CC8observedAA1SVyxGvpAA1PRzlACyxGTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>, @in_guaranteed C<τ_0_0>) -> () + // CHECK-SAME: getter @$s8keypaths1CC8observedAA1SVyxGvpAA1PRzlACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out S<τ_0_0>, + // CHECK-SAME: setter @$s8keypaths1CC8observedAA1SVyxGvpAA1PRzlACyxGTk : $@convention(keypath_accessor_setter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>, @in_guaranteed C<τ_0_0>) -> () // CHECK-SAME: ) _ = \C.observed @@ -111,15 +111,15 @@ func computedProperties(_: T) { // CHECK-SAME: root $C<τ_0_0>; // CHECK-SAME: settable_property $() -> (), // CHECK-SAME: id ##C.reabstracted, - // CHECK-SAME: getter @$s8keypaths1CC12reabstractedyycvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, - // CHECK-SAME: setter @$s8keypaths1CC12reabstractedyycvpAA1PRzlACyxGTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @in_guaranteed C<τ_0_0>) -> () + // CHECK-SAME: getter @$s8keypaths1CC12reabstractedyycvpAA1PRzlACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>) -> @out @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, + // CHECK-SAME: setter @$s8keypaths1CC12reabstractedyycvpAA1PRzlACyxGTk : $@convention(keypath_accessor_setter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @in_guaranteed C<τ_0_0>) -> () // CHECK-SAME: ) _ = \C.reabstracted // CHECK: keypath $KeyPath, C>, <τ_0_0 where τ_0_0 : P> ( // CHECK-SAME: root $S<τ_0_0>; gettable_property $C<τ_0_0>, // CHECK-SAME: id @$s8keypaths1SV8computedAA1CCyxGvg : $@convention(method) <τ_0_0> (@in_guaranteed S<τ_0_0>) -> @owned C<τ_0_0>, - // CHECK-SAME: getter @$s8keypaths1SV8computedAA1CCyxGvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>) -> @out C<τ_0_0> + // CHECK-SAME: getter @$s8keypaths1SV8computedAA1CCyxGvpAA1PRzlACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>) -> @out C<τ_0_0> // CHECK-SAME: ) _ = \S.computed @@ -127,8 +127,8 @@ func computedProperties(_: T) { // CHECK-SAME: root $S<τ_0_0>; // CHECK-SAME: settable_property $C<τ_0_0>, // CHECK-SAME: id @$s8keypaths1SV8observedAA1CCyxGvg : $@convention(method) <τ_0_0> (@in_guaranteed S<τ_0_0>) -> @owned C<τ_0_0>, - // CHECK-SAME: getter @$s8keypaths1SV8observedAA1CCyxGvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>) -> @out C<τ_0_0>, - // CHECK-SAME: setter @$s8keypaths1SV8observedAA1CCyxGvpAA1PRzlACyxGTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>, @inout S<τ_0_0>) -> () + // CHECK-SAME: getter @$s8keypaths1SV8observedAA1CCyxGvpAA1PRzlACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>) -> @out C<τ_0_0>, + // CHECK-SAME: setter @$s8keypaths1SV8observedAA1CCyxGvpAA1PRzlACyxGTk : $@convention(keypath_accessor_setter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed C<τ_0_0>, @inout S<τ_0_0>) -> () // CHECK-SAME: ) _ = \S.observed _ = \S.z.nonfinal @@ -140,8 +140,8 @@ func computedProperties(_: T) { // CHECK-SAME: root $S<τ_0_0>; // CHECK-SAME: settable_property $() -> (), // CHECK-SAME: id ##S.reabstracted, - // CHECK-SAME: getter @$s8keypaths1SV12reabstractedyycvpAA1PRzlACyxGTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>) -> @out @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, - // CHECK-SAME: setter @$s8keypaths1SV12reabstractedyycvpAA1PRzlACyxGTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @inout S<τ_0_0>) -> () + // CHECK-SAME: getter @$s8keypaths1SV12reabstractedyycvpAA1PRzlACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed S<τ_0_0>) -> @out @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, + // CHECK-SAME: setter @$s8keypaths1SV12reabstractedyycvpAA1PRzlACyxGTk : $@convention(keypath_accessor_setter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>, @inout S<τ_0_0>) -> () // CHECK-SAME: ) _ = \S.reabstracted @@ -149,15 +149,15 @@ func computedProperties(_: T) { // CHECK-SAME: root $τ_0_0; // CHECK-SAME: gettable_property $Int, // CHECK-SAME: id #P.x!getter : (Self) -> () -> Int, - // CHECK-SAME: getter @$s8keypaths1PP1xSivpAaBRzlxTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out Int + // CHECK-SAME: getter @$s8keypaths1PP1xSivpAaBRzlxTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out Int // CHECK-SAME: ) _ = \T.x // CHECK: keypath $WritableKeyPath, <τ_0_0 where τ_0_0 : P> ( // CHECK-SAME: root $τ_0_0; // CHECK-SAME: settable_property $String, // CHECK-SAME: id #P.y!getter : (Self) -> () -> String, - // CHECK-SAME: getter @$s8keypaths1PP1ySSvpAaBRzlxTK : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out String, - // CHECK-SAME: setter @$s8keypaths1PP1ySSvpAaBRzlxTk : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed String, @inout τ_0_0) -> () + // CHECK-SAME: getter @$s8keypaths1PP1ySSvpAaBRzlxTK : $@convention(keypath_accessor_getter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> @out String, + // CHECK-SAME: setter @$s8keypaths1PP1ySSvpAaBRzlxTk : $@convention(keypath_accessor_setter) <τ_0_0 where τ_0_0 : P> (@in_guaranteed String, @inout τ_0_0) -> () // CHECK-SAME: ) _ = \T.y @@ -178,7 +178,7 @@ func keyPathsWithSpecificGenericInstance() { // CHECK: keypath $KeyPath, ( // CHECK-SAME: gettable_property $String, // CHECK-SAME: id @$s8keypaths1PPAAE1zSSvg - // CHECK-SAME: getter @$s8keypaths1PPAAE1zSSvpAA8ConcreteVTK : $@convention(thin) (@in_guaranteed Concrete) -> @out String + // CHECK-SAME: getter @$s8keypaths1PPAAE1zSSvpAA8ConcreteVTK : $@convention(keypath_accessor_getter) (@in_guaranteed Concrete) -> @out String _ = \Concrete.z _ = \S.computed } @@ -425,7 +425,7 @@ func check_default_subscripts() { // CHECK: [[IX:%[0-9]+]] = apply %{{[0-9]+}}([[INTX]], {{.*}} // CHECK: [[INTY:%[0-9]+]] = integer_literal $Builtin.IntLiteral, 0 // CHECK: [[IY:%[0-9]+]] = apply %{{[0-9]+}}([[INTY]], {{.*}} - // CHECK: [[KEYPATH:%[0-9]+]] = keypath $WritableKeyPath, (root $SubscriptDefaults4; settable_property $Int, id @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluig : $@convention(method) <τ_0_0 where τ_0_0 : Numeric> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults4) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTK : $@convention(thin) (@in_guaranteed SubscriptDefaults4, UnsafeRawPointer) -> @out Int, setter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTk : $@convention(thin) (@in_guaranteed Int, @inout SubscriptDefaults4, UnsafeRawPointer) -> (), indices [%$0 : $Int : $Int, %$1 : $Int : $Int], indices_equals @$sS2iTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sS2iTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[IX]], [[IY]]) + // CHECK: [[KEYPATH:%[0-9]+]] = keypath $WritableKeyPath, (root $SubscriptDefaults4; settable_property $Int, id @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluig : $@convention(method) <τ_0_0 where τ_0_0 : Numeric> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults4) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptDefaults4, @in_guaranteed (Int, Int)) -> @out Int, setter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTk : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout SubscriptDefaults4, @in_guaranteed (Int, Int)) -> (), indices [%$0 : $Int : $Int, %$1 : $Int : $Int], indices_equals @$sS2iTH : $@convention(keypath_accessor_equals) (@in_guaranteed (Int, Int), @in_guaranteed (Int, Int)) -> Bool, indices_hash @$sS2iTh : $@convention(keypath_accessor_hash) (@in_guaranteed (Int, Int)) -> Int) ([[IX]], [[IY]]) _ = \SubscriptDefaults4.[x: 0, y: 0] // CHECK: [[INTINIT:%[0-9]+]] = integer_literal $Builtin.IntLiteral, 0 @@ -434,21 +434,21 @@ func check_default_subscripts() { // CHECK: [[ALLOC:%[0-9]+]] = alloc_stack $Int // CHECK: apply [[DFN]]([[ALLOC]]) : $@convention(thin) <τ_0_0 where τ_0_0 : Numeric> () -> @out τ_0_0 // CHECK: [[LOAD:%[0-9]+]] = load [trivial] [[ALLOC]] : $*Int - // CHECK: [[KEYPATH:%[0-9]+]] = keypath $WritableKeyPath, (root $SubscriptDefaults4; settable_property $Int, id @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluig : $@convention(method) <τ_0_0 where τ_0_0 : Numeric> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults4) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTK : $@convention(thin) (@in_guaranteed SubscriptDefaults4, UnsafeRawPointer) -> @out Int, setter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTk : $@convention(thin) (@in_guaranteed Int, @inout SubscriptDefaults4, UnsafeRawPointer) -> (), indices [%$0 : $Int : $Int, %$1 : $Int : $Int], indices_equals @$sS2iTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sS2iTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[I]], [[LOAD]]) + // CHECK: [[KEYPATH:%[0-9]+]] = keypath $WritableKeyPath, (root $SubscriptDefaults4; settable_property $Int, id @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluig : $@convention(method) <τ_0_0 where τ_0_0 : Numeric> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults4) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptDefaults4, @in_guaranteed (Int, Int)) -> @out Int, setter @$s8keypaths18SubscriptDefaults4V1x1yxx_xtcSjRzluipACSiTk : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout SubscriptDefaults4, @in_guaranteed (Int, Int)) -> (), indices [%$0 : $Int : $Int, %$1 : $Int : $Int], indices_equals @$sS2iTH : $@convention(keypath_accessor_equals) (@in_guaranteed (Int, Int), @in_guaranteed (Int, Int)) -> Bool, indices_hash @$sS2iTh : $@convention(keypath_accessor_hash) (@in_guaranteed (Int, Int)) -> Int) ([[I]], [[LOAD]]) _ = \SubscriptDefaults4.[x: 0] // CHECK: [[STRX_LIT:%[0-9]+]] = string_literal utf8 "" // CHECK: [[STRX:%[0-9]+]] = apply %{{[0-9]+}}([[STRX_LIT]], {{.*}} // CHECK: [[STRY_LIT:%[0-9]+]] = string_literal utf8 "check_default_subscripts()" // CHECK: [[DEF_ARG:%[0-9]+]] = apply %{{[0-9]+}}([[STRY_LIT]], {{.*}} - // CHECK: keypath $WritableKeyPath, (root $SubscriptDefaults5; settable_property $String, id @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluig : $@convention(method) <τ_0_0 where τ_0_0 : ExpressibleByStringLiteral> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults5) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTK : $@convention(thin) (@in_guaranteed SubscriptDefaults5, UnsafeRawPointer) -> @out String, setter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTk : $@convention(thin) (@in_guaranteed String, @inout SubscriptDefaults5, UnsafeRawPointer) -> (), indices [%$0 : $String : $String, %$1 : $String : $String], indices_equals @$sS2STH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sS2STh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[STRX]], [[DEF_ARG]]) + // CHECK: keypath $WritableKeyPath, (root $SubscriptDefaults5; settable_property $String, id @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluig : $@convention(method) <τ_0_0 where τ_0_0 : ExpressibleByStringLiteral> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults5) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptDefaults5, @in_guaranteed (String, String)) -> @out String, setter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTk : $@convention(keypath_accessor_setter) (@in_guaranteed String, @inout SubscriptDefaults5, @in_guaranteed (String, String)) -> (), indices [%$0 : $String : $String, %$1 : $String : $String], indices_equals @$sS2STH : $@convention(keypath_accessor_equals) (@in_guaranteed (String, String), @in_guaranteed (String, String)) -> Bool, indices_hash @$sS2STh : $@convention(keypath_accessor_hash) (@in_guaranteed (String, String)) -> Int) ([[STRX]], [[DEF_ARG]]) _ = \SubscriptDefaults5.[x: ""] // CHECK: [[STRX_LIT:%[0-9]+]] = string_literal utf8 "" // CHECK: [[STRX:%[0-9]+]] = apply %{{[0-9]+}}([[STRX_LIT]], {{.*}} // CHECK: [[STRY_LIT:%[0-9]+]] = string_literal utf8 "" // CHECK: [[STRY:%[0-9]+]] = apply %{{[0-9]+}}([[STRY_LIT]], {{.*}} - // CHECK: keypath $WritableKeyPath, (root $SubscriptDefaults5; settable_property $String, id @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluig : $@convention(method) <τ_0_0 where τ_0_0 : ExpressibleByStringLiteral> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults5) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTK : $@convention(thin) (@in_guaranteed SubscriptDefaults5, UnsafeRawPointer) -> @out String, setter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTk : $@convention(thin) (@in_guaranteed String, @inout SubscriptDefaults5, UnsafeRawPointer) -> (), indices [%$0 : $String : $String, %$1 : $String : $String], indices_equals @$sS2STH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sS2STh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[STRX]], [[STRY]]) + // CHECK: keypath $WritableKeyPath, (root $SubscriptDefaults5; settable_property $String, id @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluig : $@convention(method) <τ_0_0 where τ_0_0 : ExpressibleByStringLiteral> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_0, SubscriptDefaults5) -> @out τ_0_0, getter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptDefaults5, @in_guaranteed (String, String)) -> @out String, setter @$s8keypaths18SubscriptDefaults5V1x1yxx_xtcs26ExpressibleByStringLiteralRzluipACSSTk : $@convention(keypath_accessor_setter) (@in_guaranteed String, @inout SubscriptDefaults5, @in_guaranteed (String, String)) -> (), indices [%$0 : $String : $String, %$1 : $String : $String], indices_equals @$sS2STH : $@convention(keypath_accessor_equals) (@in_guaranteed (String, String), @in_guaranteed (String, String)) -> Bool, indices_hash @$sS2STh : $@convention(keypath_accessor_hash) (@in_guaranteed (String, String)) -> Int) ([[STRX]], [[STRY]]) _ = \SubscriptDefaults5.[x: "", y: ""] } @@ -472,7 +472,7 @@ func test_variadics() { // CHECK: ([[ARR:%[0-9]+]], %{{[0-9]+}}) = destructure_tuple [[MAKE_ARR]] : $(Array, Builtin.RawPointer) // CHECK: [[FIN_REF:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF // CHECK: [[FIN_ARR:%[0-9]+]] = apply [[FIN_REF]]([[ARR]]) - // CHECK: keypath $KeyPath, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(thin) (@in_guaranteed SubscriptVariadic1, UnsafeRawPointer) -> @out Int, indices [%$0 : $Array : $Array], indices_equals @$sSaySiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSaySiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[FIN_ARR]]) + // CHECK: keypath $KeyPath, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptVariadic1, @in_guaranteed Array) -> @out Int, indices [%$0 : $Array : $Array], indices_equals @$sSaySiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed Array, @in_guaranteed Array) -> Bool, indices_hash @$sSaySiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed Array) -> Int) ([[FIN_ARR]]) _ = \SubscriptVariadic1.[1, 2, 3] // CHECK: [[ARR_COUNT:%[0-9]+]] = integer_literal $Builtin.Word, 1 // CHECK: [[FN_REF:%[0-9]+]] = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF @@ -480,13 +480,13 @@ func test_variadics() { // CHECK: ([[ARR:%[0-9]+]], %{{[0-9]+}}) = destructure_tuple [[MAKE_ARR]] : $(Array, Builtin.RawPointer) // CHECK: [[FIN_REF:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF // CHECK: [[FIN_ARR:%[0-9]+]] = apply [[FIN_REF]]([[ARR]]) - // CHECK: keypath $KeyPath, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(thin) (@in_guaranteed SubscriptVariadic1, UnsafeRawPointer) -> @out Int, indices [%$0 : $Array : $Array], indices_equals @$sSaySiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSaySiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[FIN_ARR]]) + // CHECK: keypath $KeyPath, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptVariadic1, @in_guaranteed Array) -> @out Int, indices [%$0 : $Array : $Array], indices_equals @$sSaySiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed Array, @in_guaranteed Array) -> Bool, indices_hash @$sSaySiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed Array) -> Int) ([[FIN_ARR]]) _ = \SubscriptVariadic1.[1] // CHECK: [[ARR_COUNT:%[0-9]+]] = integer_literal $Builtin.Word, 0 // CHECK: [[FN_REF:%[0-9]+]] = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF // CHECK: [[MAKE_ARR:%[0-9]+]] = apply [[FN_REF]]([[ARR_COUNT]]) // CHECK: ([[ARR:%[0-9]+]], %{{[0-9]+}}) = destructure_tuple [[MAKE_ARR]] : $(Array, Builtin.RawPointer) - // CHECK: keypath $KeyPath, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(thin) (@in_guaranteed SubscriptVariadic1, UnsafeRawPointer) -> @out Int, indices [%$0 : $Array : $Array], indices_equals @$sSaySiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSaySiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[ARR]]) + // CHECK: keypath $KeyPath, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptVariadic1, @in_guaranteed Array) -> @out Int, indices [%$0 : $Array : $Array], indices_equals @$sSaySiGTH : $@convention(keypath_accessor_equals) (@in_guaranteed Array, @in_guaranteed Array) -> Bool, indices_hash @$sSaySiGTh : $@convention(keypath_accessor_hash) (@in_guaranteed Array) -> Int) ([[ARR]]) _ = \SubscriptVariadic1.[] _ = \SubscriptVariadic2.["", "1"] @@ -497,7 +497,7 @@ func test_variadics() { // CHECK: ([[ARR:%[0-9]+]], %{{[0-9]+}}) = destructure_tuple [[MAKE_ARR]] : $(Array, Builtin.RawPointer) // CHECK: [[FIN_REF:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF // CHECK: [[FIN_ARR:%[0-9]+]] = apply [[FIN_REF]]([[ARR]]) - // CHECK: keypath $KeyPath, (root $SubscriptVariadic2; gettable_property $String, id @$s8keypaths18SubscriptVariadic2Vyxxd_tcs26ExpressibleByStringLiteralRzluig : $@convention(method) <τ_0_0 where τ_0_0 : ExpressibleByStringLiteral> (@guaranteed Array<τ_0_0>, SubscriptVariadic2) -> @out τ_0_0, getter @$s8keypaths18SubscriptVariadic2Vyxxd_tcs26ExpressibleByStringLiteralRzluipACSSTK : $@convention(thin) (@in_guaranteed SubscriptVariadic2, UnsafeRawPointer) -> @out String, indices [%$0 : $Array : $Array], indices_equals @$sSaySSGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSaySSGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[FIN_ARR]]) + // CHECK: keypath $KeyPath, (root $SubscriptVariadic2; gettable_property $String, id @$s8keypaths18SubscriptVariadic2Vyxxd_tcs26ExpressibleByStringLiteralRzluig : $@convention(method) <τ_0_0 where τ_0_0 : ExpressibleByStringLiteral> (@guaranteed Array<τ_0_0>, SubscriptVariadic2) -> @out τ_0_0, getter @$s8keypaths18SubscriptVariadic2Vyxxd_tcs26ExpressibleByStringLiteralRzluipACSSTK : $@convention(keypath_accessor_getter) (@in_guaranteed SubscriptVariadic2, @in_guaranteed Array) -> @out String, indices [%$0 : $Array : $Array], indices_equals @$sSaySSGTH : $@convention(keypath_accessor_equals) (@in_guaranteed Array, @in_guaranteed Array) -> Bool, indices_hash @$sSaySSGTh : $@convention(keypath_accessor_hash) (@in_guaranteed Array) -> Int) ([[FIN_ARR]]) _ = \SubscriptVariadic2.["", #function] _ = \SubscriptVariadic3.[""] diff --git a/test/SILGen/keypaths_inlinable.swift b/test/SILGen/keypaths_inlinable.swift index f72f0fe7985a4..0373070cb0a9b 100644 --- a/test/SILGen/keypaths_inlinable.swift +++ b/test/SILGen/keypaths_inlinable.swift @@ -14,33 +14,33 @@ public struct KeypathStruct { // CHECK-LABEL: sil [serialized] [ossa] @$s18keypaths_inlinable11usesKeypathyyF : $@convention(thin) () -> () @inlinable public func usesKeypath() { // FRAGILE: keypath $WritableKeyPath, (root $KeypathStruct; stored_property #KeypathStruct.stored : $Int) - // RESILIENT: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $Int, id @$s18keypaths_inlinable13KeypathStructV6storedSivg : $@convention(method) (@in_guaranteed KeypathStruct) -> Int, getter @$s18keypaths_inlinable13KeypathStructV6storedSivpACTKq : $@convention(thin) (@in_guaranteed KeypathStruct) -> @out Int, setter @$s18keypaths_inlinable13KeypathStructV6storedSivpACTkq : $@convention(thin) (@in_guaranteed Int, @inout KeypathStruct) -> (), external #KeypathStruct.stored) + // RESILIENT: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $Int, id @$s18keypaths_inlinable13KeypathStructV6storedSivg : $@convention(method) (@in_guaranteed KeypathStruct) -> Int, getter @$s18keypaths_inlinable13KeypathStructV6storedSivpACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct) -> @out Int, setter @$s18keypaths_inlinable13KeypathStructV6storedSivpACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout KeypathStruct) -> (), external #KeypathStruct.stored) _ = \KeypathStruct.stored - // FRAGILE: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $String, id @$s18keypaths_inlinable13KeypathStructV8computedSSvg : $@convention(method) (KeypathStruct) -> @owned String, getter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq : $@convention(thin) (@in_guaranteed KeypathStruct) -> @out String, setter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTkq : $@convention(thin) (@in_guaranteed String, @inout KeypathStruct) -> () - // RESILIENT: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $String, id @$s18keypaths_inlinable13KeypathStructV8computedSSvg : $@convention(method) (@in_guaranteed KeypathStruct) -> @owned String, getter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq : $@convention(thin) (@in_guaranteed KeypathStruct) -> @out String, setter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTkq : $@convention(thin) (@in_guaranteed String, @inout KeypathStruct) -> (), external #KeypathStruct.computed + // FRAGILE: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $String, id @$s18keypaths_inlinable13KeypathStructV8computedSSvg : $@convention(method) (KeypathStruct) -> @owned String, getter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct) -> @out String, setter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed String, @inout KeypathStruct) -> () + // RESILIENT: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $String, id @$s18keypaths_inlinable13KeypathStructV8computedSSvg : $@convention(method) (@in_guaranteed KeypathStruct) -> @owned String, getter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct) -> @out String, setter @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed String, @inout KeypathStruct) -> (), external #KeypathStruct.computed _ = \KeypathStruct.computed - // FRAGILE: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $Bool, id @$s18keypaths_inlinable13KeypathStructVySbSi_SStcig : $@convention(method) (Int, @guaranteed String, KeypathStruct) -> Bool, getter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTKq : $@convention(thin) (@in_guaranteed KeypathStruct, UnsafeRawPointer) -> @out Bool, setter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTkq : $@convention(thin) (@in_guaranteed Bool, @inout KeypathStruct, UnsafeRawPointer) -> (), indices [%$0 : $Int : $Int, %$1 : $String : $String], indices_equals @$sSiSSTHq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiSSThq : $@convention(thin) (UnsafeRawPointer) -> Int) ({{.*}}) - // RESILIENT: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $Bool, id @$s18keypaths_inlinable13KeypathStructVySbSi_SStcig : $@convention(method) (Int, @guaranteed String, @in_guaranteed KeypathStruct) -> Bool, getter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTKq : $@convention(thin) (@in_guaranteed KeypathStruct, UnsafeRawPointer) -> @out Bool, setter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTkq : $@convention(thin) (@in_guaranteed Bool, @inout KeypathStruct, UnsafeRawPointer) -> (), indices [%$0 : $Int : $Int, %$1 : $String : $String], indices_equals @$sSiSSTHq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiSSThq : $@convention(thin) (UnsafeRawPointer) -> Int, external #KeypathStruct.subscript) ({{.*}}) + // FRAGILE: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $Bool, id @$s18keypaths_inlinable13KeypathStructVySbSi_SStcig : $@convention(method) (Int, @guaranteed String, KeypathStruct) -> Bool, getter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct, @in_guaranteed (Int, String)) -> @out Bool, setter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed Bool, @inout KeypathStruct, @in_guaranteed (Int, String)) -> (), indices [%$0 : $Int : $Int, %$1 : $String : $String], indices_equals @$sSiSSTHq : $@convention(keypath_accessor_equals) (@in_guaranteed (Int, String), @in_guaranteed (Int, String)) -> Bool, indices_hash @$sSiSSThq : $@convention(keypath_accessor_hash) (@in_guaranteed (Int, String)) -> Int) ({{.*}}) + // RESILIENT: keypath $WritableKeyPath, (root $KeypathStruct; settable_property $Bool, id @$s18keypaths_inlinable13KeypathStructVySbSi_SStcig : $@convention(method) (Int, @guaranteed String, @in_guaranteed KeypathStruct) -> Bool, getter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct, @in_guaranteed (Int, String)) -> @out Bool, setter @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed Bool, @inout KeypathStruct, @in_guaranteed (Int, String)) -> (), indices [%$0 : $Int : $Int, %$1 : $String : $String], indices_equals @$sSiSSTHq : $@convention(keypath_accessor_equals) (@in_guaranteed (Int, String), @in_guaranteed (Int, String)) -> Bool, indices_hash @$sSiSSThq : $@convention(keypath_accessor_hash) (@in_guaranteed (Int, String)) -> Int, external #KeypathStruct.subscript) ({{.*}}) _ = \KeypathStruct[0, ""] } -// RESILIENT-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV6storedSivpACTKq : $@convention(thin) (@in_guaranteed KeypathStruct) -> @out Int +// RESILIENT-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV6storedSivpACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct) -> @out Int // RESILIENT: function_ref @$s18keypaths_inlinable13KeypathStructV6storedSivg -// RESILIENT-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV6storedSivpACTkq : $@convention(thin) (@in_guaranteed Int, @inout KeypathStruct) -> () +// RESILIENT-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV6storedSivpACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @inout KeypathStruct) -> () // RESILIENT: function_ref @$s18keypaths_inlinable13KeypathStructV6storedSivs -// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq : $@convention(thin) (@in_guaranteed KeypathStruct) -> @out String +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct) -> @out String -// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTkq : $@convention(thin) (@in_guaranteed String, @inout KeypathStruct) -> () +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructV8computedSSvpACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed String, @inout KeypathStruct) -> () -// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSiSSTHq : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSiSSTHq : $@convention(keypath_accessor_equals) (@in_guaranteed (Int, String), @in_guaranteed (Int, String)) -> Bool -// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSiSSThq : $@convention(thin) (UnsafeRawPointer) -> Int +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$sSiSSThq : $@convention(keypath_accessor_hash) (@in_guaranteed (Int, String)) -> Int -// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTKq : $@convention(thin) (@in_guaranteed KeypathStruct, UnsafeRawPointer) -> @out Bool +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTKq : $@convention(keypath_accessor_getter) (@in_guaranteed KeypathStruct, @in_guaranteed (Int, String)) -> @out Bool -// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTkq : $@convention(thin) (@in_guaranteed Bool, @inout KeypathStruct, UnsafeRawPointer) -> () +// CHECK-LABEL: sil shared [serialized] [thunk] [ossa] @$s18keypaths_inlinable13KeypathStructVySbSi_SStcipACTkq : $@convention(keypath_accessor_setter) (@in_guaranteed Bool, @inout KeypathStruct, @in_guaranteed (Int, String)) -> () diff --git a/test/SILGen/keypaths_resilient_generic.swift b/test/SILGen/keypaths_resilient_generic.swift index 2a398ea6bd213..de883054da853 100644 --- a/test/SILGen/keypaths_resilient_generic.swift +++ b/test/SILGen/keypaths_resilient_generic.swift @@ -14,15 +14,15 @@ open class ConcreteSubclass : MySubclass { public final var anotherStoredProperty: Int? = nil } -// CHECK-LABEL: sil shared [thunk] [ossa] @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTK : $@convention(thin) (@in_guaranteed MySubclass) -> @out Optional { +// CHECK-LABEL: sil shared [thunk] [ossa] @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTK : $@convention(keypath_accessor_getter) (@in_guaranteed MySubclass) -> @out Optional { -// CHECK-LABEL: sil shared [thunk] [ossa] @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTk : $@convention(thin) (@in_guaranteed Optional, @in_guaranteed MySubclass) -> () { +// CHECK-LABEL: sil shared [thunk] [ossa] @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTk : $@convention(keypath_accessor_setter) (@in_guaranteed Optional, @in_guaranteed MySubclass) -> () { // CHECK: sil_property #MySubclass.storedProperty<τ_0_0> ( // CHECK-SAME: settable_property $Optional<τ_0_0>, // CHECK-SAME: id ##MySubclass.storedProperty, -// CHECK-SAME: getter @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTK : $@convention(thin) <τ_0_0> (@in_guaranteed MySubclass<τ_0_0>) -> @out Optional<τ_0_0>, -// CHECK-SAME: setter @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTk : $@convention(thin) <τ_0_0> (@in_guaranteed Optional<τ_0_0>, @in_guaranteed MySubclass<τ_0_0>) -> () +// CHECK-SAME: getter @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTK : $@convention(keypath_accessor_getter) <τ_0_0> (@in_guaranteed MySubclass<τ_0_0>) -> @out Optional<τ_0_0>, +// CHECK-SAME: setter @$s26keypaths_resilient_generic10MySubclassC14storedPropertyxSgvplACyxGTk : $@convention(keypath_accessor_setter) <τ_0_0> (@in_guaranteed Optional<τ_0_0>, @in_guaranteed MySubclass<τ_0_0>) -> () // CHECK-SAME: ) // CHECK: sil_property #ConcreteSubclass.anotherStoredProperty ( diff --git a/test/SILGen/opaque_result_type_class_property.swift b/test/SILGen/opaque_result_type_class_property.swift index 042f1b60c111e..3d54dc818b632 100644 --- a/test/SILGen/opaque_result_type_class_property.swift +++ b/test/SILGen/opaque_result_type_class_property.swift @@ -7,8 +7,8 @@ public class HasProperty { public var foo: some V = E() } -// CHECK-LABEL: sil shared [thunk] [ossa] @$s33opaque_result_type_class_property11HasPropertyC3fooQrvpACTK : $@convention(thin) (@in_guaranteed HasProperty) -> @out @_opaqueReturnTypeOf("$s33opaque_result_type_class_property11HasPropertyC3fooQrvp", 0) __ { +// CHECK-LABEL: sil shared [thunk] [ossa] @$s33opaque_result_type_class_property11HasPropertyC3fooQrvpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed HasProperty) -> @out @_opaqueReturnTypeOf("$s33opaque_result_type_class_property11HasPropertyC3fooQrvp", 0) __ { // CHECK: bb0(%0 : $*E, %1 : $*HasProperty): -// CHECK-LABEL: sil shared [thunk] [ossa] @$s33opaque_result_type_class_property11HasPropertyC3fooQrvpACTk : $@convention(thin) (@in_guaranteed @_opaqueReturnTypeOf("$s33opaque_result_type_class_property11HasPropertyC3fooQrvp", 0) __, @in_guaranteed HasProperty) -> () { +// CHECK-LABEL: sil shared [thunk] [ossa] @$s33opaque_result_type_class_property11HasPropertyC3fooQrvpACTk : $@convention(keypath_accessor_setter) (@in_guaranteed @_opaqueReturnTypeOf("$s33opaque_result_type_class_property11HasPropertyC3fooQrvp", 0) __, @in_guaranteed HasProperty) -> () { // CHECK: bb0(%0 : $*E, %1 : $*HasProperty): diff --git a/test/SILGen/property_wrapper_coroutine_public.swift b/test/SILGen/property_wrapper_coroutine_public.swift index 188df59cfb5e4..db0ddbf8caaf7 100644 --- a/test/SILGen/property_wrapper_coroutine_public.swift +++ b/test/SILGen/property_wrapper_coroutine_public.swift @@ -29,5 +29,5 @@ public class Store { } // CHECK-LABEL: sil [ossa] @$s33property_wrapper_coroutine_public5StoreC5stateypvM : $@yield_once @convention(method) (@guaranteed Store) -> @yields @inout Any { -// CHECK: keypath $ReferenceWritableKeyPath, (root $Store; settable_property $Any, id #Store.state!getter : (Store) -> () -> Any, getter @$s33property_wrapper_coroutine_public5StoreC5stateypvpACTK : $@convention(thin) (@in_guaranteed Store) -> @out Any, setter @$s33property_wrapper_coroutine_public5StoreC5stateypvpACTk : $@convention(thin) (@in_guaranteed Any, @in_guaranteed Store) -> ()) +// CHECK: keypath $ReferenceWritableKeyPath, (root $Store; settable_property $Any, id #Store.state!getter : (Store) -> () -> Any, getter @$s33property_wrapper_coroutine_public5StoreC5stateypvpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed Store) -> @out Any, setter @$s33property_wrapper_coroutine_public5StoreC5stateypvpACTk : $@convention(keypath_accessor_setter) (@in_guaranteed Any, @in_guaranteed Store) -> ()) // CHECK: keypath $ReferenceWritableKeyPath>, (root $Store; stored_property #Store._state : $Published) diff --git a/test/SILOptimizer/access_wmo.sil b/test/SILOptimizer/access_wmo.sil index d6512521af731..a714a6b254705 100644 --- a/test/SILOptimizer/access_wmo.sil +++ b/test/SILOptimizer/access_wmo.sil @@ -176,7 +176,7 @@ bb0(%0 : $C): // CHECK: begin_unpaired_access [modify] [dynamic] [[E3]] : $*Int64, %{{.*}} : $*Builtin.UnsafeValueBuffer // CHECK: [[E4:%.*]] = ref_element_addr %0 : $C, #C.internalProp // CHECK: begin_unpaired_access [modify] [dynamic] [[E4]] : $*Int64, %{{.*}} : $*Builtin.UnsafeValueBuffer -// CHECK: keypath $ReferenceWritableKeyPath, (root $C; settable_property $Int64, id #C.keyPathProp!getter : (C) -> () -> Int64, getter @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(thin) (@in_guaranteed C) -> @out Int64, setter @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(thin) (@in_guaranteed Int64, @in_guaranteed C) -> ()) +// CHECK: keypath $ReferenceWritableKeyPath, (root $C; settable_property $Int64, id #C.keyPathProp!getter : (C) -> () -> Int64, getter @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int64, setter @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(keypath_accessor_setter) (@in_guaranteed Int64, @in_guaranteed C) -> ()) // CHECK: keypath $ReferenceWritableKeyPath, (root $C; stored_property #C.finalKeyPathProp : $Int64) // CHECK: [[E5:%.*]] = ref_element_addr %0 : $C, #C.publicProp // CHECK: begin_unpaired_access [modify] [dynamic] [[E5]] : $*Int64, %{{.*}} : $*Builtin.UnsafeValueBuffer @@ -207,7 +207,7 @@ bb0(%0 : $C, %1 : $Int64): %22 = apply %8(%21, %1) : $@convention(thin) (@inout Int64, Int64) -> () end_unpaired_access [dynamic] %18 : $*Builtin.UnsafeValueBuffer dealloc_stack %18 : $*Builtin.UnsafeValueBuffer - %25 = keypath $ReferenceWritableKeyPath, (root $C; settable_property $Int64, id #C.keyPathProp!getter : (C) -> () -> Int64, getter @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(thin) (@in_guaranteed C) -> @out Int64, setter @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(thin) (@in_guaranteed Int64, @in_guaranteed C) -> ()) + %25 = keypath $ReferenceWritableKeyPath, (root $C; settable_property $Int64, id #C.keyPathProp!getter : (C) -> () -> Int64, getter @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int64, setter @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(keypath_accessor_setter) (@in_guaranteed Int64, @in_guaranteed C) -> ()) // function_ref setKeyPath(_:_:_:) %26 = function_ref @$s10access_wmo10setKeyPathyyAA1CC_s017ReferenceWritabledE0CyADSiGSitF : $@convention(thin) (@guaranteed C, @guaranteed ReferenceWritableKeyPath, Int64) -> () %27 = apply %26(%0, %25, %1) : $@convention(thin) (@guaranteed C, @guaranteed ReferenceWritableKeyPath, Int64) -> () @@ -228,10 +228,10 @@ bb0(%0 : $C, %1 : $Int64): // key path getter for C.keyPathProp : C // -// CHECK-LABEL: sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(thin) (@in_guaranteed C) -> @out Int64 { +// CHECK-LABEL: sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int64 { // CHECK: begin_access [read] [static] [no_nested_conflict] %{{.*}} : $*Int64 // CHECK-LABEL: } // end sil function '$s10access_wmo1CC11keyPathPropSivpACTK' -sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(thin) (@in_guaranteed C) -> @out Int64 { +sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int64 { bb0(%0 : $*Int64, %1 : $*C): %2 = load %1 : $*C // user: %3 %3 = ref_element_addr %2 : $C, #C.keyPathProp // user: %4 @@ -245,10 +245,10 @@ bb0(%0 : $*Int64, %1 : $*C): // key path setter for C.keyPathProp : C // -// CHECK-LABEL: sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(thin) (@in_guaranteed Int64, @in_guaranteed C) -> () { +// CHECK-LABEL: sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(keypath_accessor_setter) (@in_guaranteed Int64, @in_guaranteed C) -> () { // CHECK: begin_access [modify] [static] [no_nested_conflict] %{{.*}} : $*Int64 // CHECK-LABEL: } // end sil function '$s10access_wmo1CC11keyPathPropSivpACTk' -sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(thin) (@in_guaranteed Int64, @in_guaranteed C) -> () { +sil shared [thunk] @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(keypath_accessor_setter) (@in_guaranteed Int64, @in_guaranteed C) -> () { bb0(%0 : $*Int64, %1 : $*C): %2 = load %0 : $*Int64 // user: %6 %3 = load %1 : $*C // user: %4 diff --git a/test/SILOptimizer/access_wmo.swift b/test/SILOptimizer/access_wmo.swift index 7c640ca1abd91..e2f1cd5b65e35 100644 --- a/test/SILOptimizer/access_wmo.swift +++ b/test/SILOptimizer/access_wmo.swift @@ -225,7 +225,7 @@ public func testAccessProp(c: C, v: Int) { // WMO: apply [[F1]]([[A4]], %1) : $@convention(thin) (@inout Int, Int) -> () // WMO: end_access [[A4]] // -// WMO: [[KP:%.*]] = keypath $ReferenceWritableKeyPath, (root $C; settable_property $Int, id #C.keyPathProp!getter : (C) -> () -> Int, getter @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(thin) (@in_guaranteed C) -> @out Int, setter @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(thin) (@in_guaranteed Int, @in_guaranteed C) -> ()) +// WMO: [[KP:%.*]] = keypath $ReferenceWritableKeyPath, (root $C; settable_property $Int, id #C.keyPathProp!getter : (C) -> () -> Int, getter @$s10access_wmo1CC11keyPathPropSivpACTK : $@convention(keypath_accessor_getter) (@in_guaranteed C) -> @out Int, setter @$s10access_wmo1CC11keyPathPropSivpACTk : $@convention(keypath_accessor_setter) (@in_guaranteed Int, @in_guaranteed C) -> ()) // function_ref setKeyPath(_:_:_:) // WMO: [[F2:%.*]] = function_ref @$s10access_wmo10setKeyPathyyAA1CC_s017ReferenceWritabledE0CyADSiGSitF : $@convention(thin) (@guaranteed C, @guaranteed ReferenceWritableKeyPath, Int) -> () // WMO: apply [[F2]](%0, [[KP]], %1) : $@convention(thin) (@guaranteed C, @guaranteed ReferenceWritableKeyPath, Int) -> () diff --git a/test/SILOptimizer/dead_alloc_elim.sil b/test/SILOptimizer/dead_alloc_elim.sil index 45aba104bda59..8f69a734ba62a 100644 --- a/test/SILOptimizer/dead_alloc_elim.sil +++ b/test/SILOptimizer/dead_alloc_elim.sil @@ -652,9 +652,9 @@ struct I { struct S2 { } sil @getter : $@convention(method) (@guaranteed KeyPath, S2) -> @out II -sil @kpgetter : $@convention(thin) (@in_guaranteed S2, UnsafeRawPointer) -> @out II -sil @equ : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool -sil @hsh : $@convention(thin) (UnsafeRawPointer) -> Int +sil @kpgetter : $@convention(keypath_accessor_getter) (@in_guaranteed S2, @in_guaranteed KeyPath) -> @out II +sil @equ : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool +sil @hsh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int // CHECK-LABEL: sil @remove_dead_keypath @@ -663,7 +663,7 @@ sil @hsh : $@convention(thin) (UnsafeRawPointer) -> Int sil @remove_dead_keypath: $@convention(thin) () -> () { bb0: %0 = keypath $KeyPath, (root $I; stored_property #I.x : $II) - %1 = keypath $KeyPath, (root $S2; gettable_property $II, id @getter : $@convention(method) (@guaranteed KeyPath, S2) -> @out II, getter @kpgetter: $@convention(thin) (@in_guaranteed S2, UnsafeRawPointer) -> @out II, indices [%$0 : $KeyPath : $KeyPath], indices_equals @equ : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @hsh : $@convention(thin) (UnsafeRawPointer) -> Int) (%0) + %1 = keypath $KeyPath, (root $S2; gettable_property $II, id @getter : $@convention(method) (@guaranteed KeyPath, S2) -> @out II, getter @kpgetter: $@convention(keypath_accessor_getter) (@in_guaranteed S2, @in_guaranteed KeyPath) -> @out II, indices [%$0 : $KeyPath : $KeyPath], indices_equals @equ : $@convention(keypath_accessor_equals) (@in_guaranteed KeyPath, @in_guaranteed KeyPath) -> Bool, indices_hash @hsh : $@convention(keypath_accessor_hash) (@in_guaranteed KeyPath) -> Int) (%0) %r = tuple () return %r : $() diff --git a/test/SILOptimizer/optimize_keypath.swift b/test/SILOptimizer/optimize_keypath.swift index 92d34bedbc9a5..8a902604ddcc7 100644 --- a/test/SILOptimizer/optimize_keypath.swift +++ b/test/SILOptimizer/optimize_keypath.swift @@ -5,7 +5,6 @@ // RUN: %target-build-swift -O %s -o %t/a.out // RUN: %target-run %t/a.out | %FileCheck %s -check-prefix=CHECK-OUTPUT -// REQUIRES: executable_test,swift_stdlib_no_asserts,optimized_stdlib // REQUIRES: CPU=arm64 || CPU=x86_64 protocol P { diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil index d7172d7c51deb..00ff82a3b5b9b 100644 --- a/test/SILOptimizer/sil_combine.sil +++ b/test/SILOptimizer/sil_combine.sil @@ -4280,8 +4280,8 @@ class Kp2 { init() } -sil @kpgetter : $@convention(thin) (@in_guaranteed Kp2) -> @out String -sil @kpsetter : $@convention(thin) (@in_guaranteed String, @in_guaranteed Kp2) -> () +sil @kpgetter : $@convention(keypath_accessor_getter) (@in_guaranteed Kp2) -> @out String +sil @kpsetter : $@convention(keypath_accessor_setter) (@in_guaranteed String, @in_guaranteed Kp2) -> () sil @swift_getAtKeyPath : $@convention(thin) <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0, @guaranteed KeyPath<τ_0_0, τ_0_1>) -> @out τ_0_1 // Test keypath optimization for optional chaining with accesses scopes. @@ -4299,7 +4299,7 @@ sil @swift_getAtKeyPath : $@convention(thin) <τ_0_0, τ_0_1> (@in_guaranteed τ // CHECK: } // end sil function 'test_optional_chaining_keypath' sil @test_optional_chaining_keypath : $@convention(thin) (@in_guaranteed Kp1) -> @out Optional { bb0(%0 : $*Optional, %1 : $*Kp1): - %kp = keypath $KeyPath>, (root $Kp1; stored_property #Kp1.b : $Optional; optional_chain : $Kp2; settable_property $String, id #Kp2.s!getter : (Kp2) -> () -> String, getter @kpgetter : $@convention(thin) (@in_guaranteed Kp2) -> @out String, setter @kpsetter : $@convention(thin) (@in_guaranteed String, @in_guaranteed Kp2) -> (); optional_wrap : $Optional) + %kp = keypath $KeyPath>, (root $Kp1; stored_property #Kp1.b : $Optional; optional_chain : $Kp2; settable_property $String, id #Kp2.s!getter : (Kp2) -> () -> String, getter @kpgetter : $@convention(keypath_accessor_getter) (@in_guaranteed Kp2) -> @out String, setter @kpsetter : $@convention(keypath_accessor_setter) (@in_guaranteed String, @in_guaranteed Kp2) -> (); optional_wrap : $Optional) %f = function_ref @swift_getAtKeyPath : $@convention(thin) <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0, @guaranteed KeyPath<τ_0_0, τ_0_1>) -> @out τ_0_1 %a = apply %f>(%0, %1, %kp) : $@convention(thin) <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0, @guaranteed KeyPath<τ_0_0, τ_0_1>) -> @out τ_0_1 strong_release %kp : $KeyPath>