diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst index f50f7d764acef..5bc224ce6af96 100644 --- a/docs/ABI/Mangling.rst +++ b/docs/ABI/Mangling.rst @@ -591,8 +591,8 @@ Types FUNCTION-KIND ::= 'B' // objc block function type FUNCTION-KIND ::= 'zB' C-TYPE // objc block type with non-canonical C type FUNCTION-KIND ::= 'L' // objc block function type with canonical C type (escaping) (DWARF only; otherwise use 'B' or 'zB' C-TYPE) - FUNCTION-KIND ::= 'C' // C function pointer type - FUNCTION-KIND ::= 'zC' C-TYPE // C function pointer type with with non-canonical C type + FUNCTION-KIND ::= 'C' // C function pointer / C++ method type + FUNCTION-KIND ::= 'zC' C-TYPE // C function pointer / C++ method type with with non-canonical C type FUNCTION-KIND ::= 'A' // @auto_closure function type (escaping) FUNCTION-KIND ::= 'E' // function type (noescape) diff --git a/include/swift/AST/ExtInfo.h b/include/swift/AST/ExtInfo.h index 6007b52bbbb26..22dc42fd4027f 100644 --- a/include/swift/AST/ExtInfo.h +++ b/include/swift/AST/ExtInfo.h @@ -167,6 +167,11 @@ enum class SILFunctionTypeRepresentation : uint8_t { /// A closure invocation function that has not been bound to a context. Closure, + + /// A C++ method that takes a "this" argument (not a static C++ method or + /// constructor). Except for + /// handling the "this" argument, has the same behavior as "CFunctionPointer". + CXXMethod, }; /// Returns true if the function with this convention doesn't carry a context. @@ -196,6 +201,7 @@ isThinRepresentation(SILFunctionTypeRepresentation rep) { case SILFunctionTypeRepresentation::WitnessMethod: case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::CXXMethod: return true; } llvm_unreachable("Unhandled SILFunctionTypeRepresentation in switch."); @@ -232,6 +238,7 @@ convertRepresentation(SILFunctionTypeRepresentation rep) { return {FunctionTypeRepresentation::Block}; case SILFunctionTypeRepresentation::Thin: return {FunctionTypeRepresentation::Thin}; + case SILFunctionTypeRepresentation::CXXMethod: case SILFunctionTypeRepresentation::CFunctionPointer: return {FunctionTypeRepresentation::CFunctionPointer}; case SILFunctionTypeRepresentation::Method: @@ -252,6 +259,7 @@ constexpr bool canBeCalledIndirectly(SILFunctionTypeRepresentation rep) { case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::Block: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::CXXMethod: return false; case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::Method: @@ -269,6 +277,7 @@ template constexpr bool shouldStoreClangType(Repr repr) { switch (static_cast(repr)) { case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::Block: + case SILFunctionTypeRepresentation::CXXMethod: return true; case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::Thick: @@ -392,6 +401,7 @@ class ASTExtInfoBuilder { case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::WitnessMethod: + case SILFunctionTypeRepresentation::CXXMethod: return true; } llvm_unreachable("Unhandled SILFunctionTypeRepresentation in switch."); @@ -618,6 +628,7 @@ SILFunctionLanguage getSILFunctionLanguage(SILFunctionTypeRepresentation rep) { case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::Block: + case SILFunctionTypeRepresentation::CXXMethod: return SILFunctionLanguage::C; case SILFunctionTypeRepresentation::Thick: case SILFunctionTypeRepresentation::Thin: @@ -750,6 +761,7 @@ class SILExtInfoBuilder { case Representation::ObjCMethod: case Representation::Method: case Representation::WitnessMethod: + case SILFunctionTypeRepresentation::CXXMethod: return true; } llvm_unreachable("Unhandled Representation in switch."); @@ -767,6 +779,7 @@ class SILExtInfoBuilder { case Representation::Method: case Representation::WitnessMethod: case Representation::Closure: + case SILFunctionTypeRepresentation::CXXMethod: return false; } llvm_unreachable("Unhandled Representation in switch."); diff --git a/include/swift/SIL/ApplySite.h b/include/swift/SIL/ApplySite.h index a0d6e866030b7..999352c38455a 100644 --- a/include/swift/SIL/ApplySite.h +++ b/include/swift/SIL/ApplySite.h @@ -237,6 +237,7 @@ class ApplySite { bool isCalleeThin() const { switch (getSubstCalleeType()->getRepresentation()) { case SILFunctionTypeRepresentation::CFunctionPointer: + case SILFunctionTypeRepresentation::CXXMethod: case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::ObjCMethod: diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 3f5a905e7788d..39f20e919b8aa 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -129,6 +129,8 @@ getSILFunctionTypeRepresentationString(SILFunctionType::Representation value) { case SILFunctionType::Representation::Thick: return "thick"; case SILFunctionType::Representation::Block: return "block"; case SILFunctionType::Representation::CFunctionPointer: return "c"; + case SILFunctionType::Representation::CXXMethod: + return "cxx_method"; case SILFunctionType::Representation::Thin: return "thin"; case SILFunctionType::Representation::Method: return "method"; case SILFunctionType::Representation::ObjCMethod: return "objc_method"; diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp index 68286cbdb8b94..8e3e7b15565ad 100644 --- a/lib/AST/ASTMangler.cpp +++ b/lib/AST/ASTMangler.cpp @@ -1828,6 +1828,7 @@ void ASTMangler::appendImplFunctionType(SILFunctionType *fn, OpArgs.push_back('B'); appendClangTypeToVec(OpArgs); break; + case SILFunctionTypeRepresentation::CXXMethod: case SILFunctionTypeRepresentation::CFunctionPointer: if (!mangleClangType) { OpArgs.push_back('C'); diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index b0f799c7694af..5f38096a0bd28 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -4885,6 +4885,9 @@ class TypePrinter : public TypeVisitor { case SILFunctionType::Representation::Method: Printer << "method"; break; + case SILFunctionType::Representation::CXXMethod: + Printer << "cxx_method"; + break; case SILFunctionType::Representation::ObjCMethod: Printer << "objc_method"; break; @@ -4963,6 +4966,9 @@ class TypePrinter : public TypeVisitor { case SILFunctionType::Representation::Method: Printer << "method"; break; + case SILFunctionType::Representation::CXXMethod: + Printer << "cxx_method"; + break; case SILFunctionType::Representation::ObjCMethod: Printer << "objc_method"; break; diff --git a/lib/AST/ClangTypeConverter.cpp b/lib/AST/ClangTypeConverter.cpp index 5b1010dd8e051..7a1a4eca5b6f4 100644 --- a/lib/AST/ClangTypeConverter.cpp +++ b/lib/AST/ClangTypeConverter.cpp @@ -212,6 +212,7 @@ const clang::Type *ClangTypeConverter::getFunctionType( return nullptr; switch (repr) { + case SILFunctionType::Representation::CXXMethod: case SILFunctionType::Representation::CFunctionPointer: return ClangASTContext.getPointerType(fn).getTypePtr(); case SILFunctionType::Representation::Block: diff --git a/lib/AST/ExtInfo.cpp b/lib/AST/ExtInfo.cpp index a7b2d74955b41..9f37b0ae1409a 100644 --- a/lib/AST/ExtInfo.cpp +++ b/lib/AST/ExtInfo.cpp @@ -68,6 +68,7 @@ Optional UnexpectedClangTypeError::checkClangType( #else bool isBlock = true; switch (silRep) { + case SILFunctionTypeRepresentation::CXXMethod: case SILFunctionTypeRepresentation::CFunctionPointer: isBlock = false; LLVM_FALLTHROUGH; diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 400a3a7befcbd..9baa1b3da2893 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -4085,18 +4085,20 @@ namespace { templateParams); if (auto *mdecl = dyn_cast(decl)) { + // Subscripts and call operators are imported as normal methods. + bool staticOperator = mdecl->isOverloadedOperator() && + mdecl->getOverloadedOperator() != clang::OO_Call && + mdecl->getOverloadedOperator() != clang::OO_Subscript; if (mdecl->isStatic() || // C++ operators that are implemented as non-static member // functions get imported into Swift as static member functions // that use an additional parameter for the left-hand side operand // instead of the receiver object. - (mdecl->getDeclName().getNameKind() == - clang::DeclarationName::CXXOperatorName && - isImportedAsStatic(mdecl->getOverloadedOperator()))) { + staticOperator) { selfIdx = None; } else { - selfIdx = 0; - // Don't import members of a class decl as mutating. + // Swift imports the "self" param last, even for clang functions. + selfIdx = bodyParams ? bodyParams->size() : 0; // If the method is imported as mutating, this implicitly makes the // parameter indirect. selfIsInOut = diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp index 13779d994e4a9..1273db09499a0 100644 --- a/lib/ClangImporter/ImportType.cpp +++ b/lib/ClangImporter/ImportType.cpp @@ -1897,7 +1897,11 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList( // imported into Swift as static methods that have an additional // parameter for the left-hand side operand instead of the receiver object. if (auto CMD = dyn_cast(clangDecl)) { - if (clangDecl->isOverloadedOperator() && isImportedAsStatic(clangDecl->getOverloadedOperator())) { + // Subscripts and call operators are imported as normal methods. + bool staticOperator = clangDecl->isOverloadedOperator() && + clangDecl->getOverloadedOperator() != clang::OO_Call && + clangDecl->getOverloadedOperator() != clang::OO_Subscript; + if (staticOperator) { auto param = new (SwiftContext) ParamDecl(SourceLoc(), SourceLoc(), Identifier(), SourceLoc(), SwiftContext.getIdentifier("lhs"), dc); diff --git a/lib/IRGen/Callee.h b/lib/IRGen/Callee.h index 3cf37cbf9757c..e1627f4f58f49 100644 --- a/lib/IRGen/Callee.h +++ b/lib/IRGen/Callee.h @@ -462,6 +462,9 @@ namespace irgen { /// Given that this callee is a block, return the block pointer. llvm::Value *getBlockObject() const; + /// Given that this callee is a C++ method, return the self argument. + llvm::Value *getCXXMethodSelf() const; + /// Given that this callee is an ObjC method, return the receiver /// argument. This might not be 'self' anymore. llvm::Value *getObjCMethodReceiver() const; diff --git a/lib/IRGen/GenCall.cpp b/lib/IRGen/GenCall.cpp index 2fb3644348e82..2ff627dfd47a3 100644 --- a/lib/IRGen/GenCall.cpp +++ b/lib/IRGen/GenCall.cpp @@ -293,6 +293,7 @@ llvm::CallingConv::ID irgen::expandCallingConv(IRGenModule &IGM, switch (convention) { case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::ObjCMethod: + case SILFunctionTypeRepresentation::CXXMethod: case SILFunctionTypeRepresentation::Block: return llvm::CallingConv::C; @@ -1326,6 +1327,7 @@ void SignatureExpansion::expandExternalSignatureTypes() { paramTys.push_back(clangCtx.VoidPtrTy); break; + case SILFunctionTypeRepresentation::CXXMethod: case SILFunctionTypeRepresentation::CFunctionPointer: // No implicit arguments. break; @@ -1642,6 +1644,7 @@ void SignatureExpansion::expandParameters() { case SILFunctionType::Representation::Method: case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::ObjCMethod: + case SILFunctionType::Representation::CXXMethod: case SILFunctionType::Representation::Thin: case SILFunctionType::Representation::Closure: return FnType->hasErrorResult(); @@ -1809,6 +1812,7 @@ void SignatureExpansion::expandAsyncEntryType() { case SILFunctionType::Representation::ObjCMethod: case SILFunctionType::Representation::Thin: case SILFunctionType::Representation::Closure: + case SILFunctionType::Representation::CXXMethod: return false; case SILFunctionType::Representation::Thick: @@ -2203,7 +2207,20 @@ class SyncCallEmission final : public CallEmission { break; case SILFunctionTypeRepresentation::Block: - adjusted.add(getCallee().getBlockObject()); + case SILFunctionTypeRepresentation::CXXMethod: + if (getCallee().getRepresentation() == SILFunctionTypeRepresentation::Block) { + adjusted.add(getCallee().getBlockObject()); + } else { + auto selfParam = origCalleeType->getSelfParameter(); + auto *arg = getCallee().getCXXMethodSelf(); + // We might need to fix the level of indirection for foreign reference types. + if (selfParam.getInterfaceType().isForeignReferenceType() && + isIndirectFormalParameter(selfParam.getConvention())) + arg = IGF.Builder.CreateLoad(arg, IGF.IGM.getPointerAlignment()); + + adjusted.add(arg); + } + LLVM_FALLTHROUGH; case SILFunctionTypeRepresentation::CFunctionPointer: @@ -2462,14 +2479,9 @@ class AsyncCallEmission final : public CallEmission { // Translate the formal arguments and handle any special arguments. switch (getCallee().getRepresentation()) { case SILFunctionTypeRepresentation::ObjCMethod: - assert(false && "Should not reach this"); - break; - case SILFunctionTypeRepresentation::Block: - assert(false && "Should not reach this"); - break; - case SILFunctionTypeRepresentation::CFunctionPointer: + case SILFunctionTypeRepresentation::CXXMethod: assert(false && "Should not reach this"); break; @@ -3148,6 +3160,9 @@ Callee::Callee(CalleeInfo &&info, const FunctionPointer &fn, case SILFunctionTypeRepresentation::CFunctionPointer: assert(!FirstData && !SecondData); break; + case SILFunctionTypeRepresentation::CXXMethod: + assert(FirstData && !SecondData); + break; } #endif @@ -3160,6 +3175,7 @@ llvm::Value *Callee::getSwiftContext() const { case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Closure: + case SILFunctionTypeRepresentation::CXXMethod: return nullptr; case SILFunctionTypeRepresentation::WitnessMethod: @@ -3182,6 +3198,14 @@ llvm::Value *Callee::getBlockObject() const { return FirstData; } +llvm::Value *Callee::getCXXMethodSelf() const { + assert(Info.OrigFnType->getRepresentation() == + SILFunctionTypeRepresentation::CXXMethod && + "not a C++ method"); + assert(FirstData && "no self object set on callee"); + return FirstData; +} + llvm::Value *Callee::getObjCMethodReceiver() const { assert(Info.OrigFnType->getRepresentation() == SILFunctionTypeRepresentation::ObjCMethod && @@ -3496,6 +3520,7 @@ static void externalizeArguments(IRGenFunction &IGF, const Callee &callee, // The index of the first "physical" parameter from paramTys/FI that // corresponds to a logical parameter from params. unsigned firstParam = 0; + unsigned paramEnd = FI.arg_size(); // Handle the ObjC prefix. if (callee.getRepresentation() == SILFunctionTypeRepresentation::ObjCMethod) { @@ -3509,14 +3534,19 @@ static void externalizeArguments(IRGenFunction &IGF, const Callee &callee, == SILFunctionTypeRepresentation::Block) { // Ignore the physical block-object parameter. firstParam += 1; - // Or the indirect result parameter. - } else if (fnType->getNumResults() > 0 && + } else if (callee.getRepresentation() == + SILFunctionTypeRepresentation::CXXMethod) { + // Skip the "self" param. + paramEnd--; + } + + if (fnType->getNumResults() > 0 && fnType->getSingleResult().isFormalIndirect()) { // Ignore the indirect result parameter. firstParam += 1; } - for (unsigned i = firstParam, e = FI.arg_size(); i != e; ++i) { + for (unsigned i = firstParam; i != paramEnd; ++i) { auto clangParamTy = FI.arg_begin()[i].type; auto &AI = FI.arg_begin()[i].info; diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp index 1b57f9368611f..f141850806b81 100644 --- a/lib/IRGen/GenFunc.cpp +++ b/lib/IRGen/GenFunc.cpp @@ -528,6 +528,7 @@ const TypeInfo *TypeConverter::convertFunctionType(SILFunctionType *T) { case SILFunctionType::Representation::Thin: case SILFunctionType::Representation::Method: + case SILFunctionType::Representation::CXXMethod: case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::ObjCMethod: case SILFunctionType::Representation::CFunctionPointer: @@ -583,6 +584,7 @@ getFuncSignatureInfoForLowered(IRGenModule &IGM, CanSILFunctionType type) { case SILFunctionType::Representation::Thin: case SILFunctionType::Representation::CFunctionPointer: case SILFunctionType::Representation::Method: + case SILFunctionType::Representation::CXXMethod: case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::ObjCMethod: case SILFunctionType::Representation::Closure: diff --git a/lib/IRGen/GenPointerAuth.cpp b/lib/IRGen/GenPointerAuth.cpp index df719af21a86d..61d434693dfaf 100644 --- a/lib/IRGen/GenPointerAuth.cpp +++ b/lib/IRGen/GenPointerAuth.cpp @@ -190,6 +190,7 @@ static const PointerAuthSchema &getFunctionPointerSchema(IRGenModule &IGM, CanSILFunctionType fnType) { auto &options = IGM.getOptions().PointerAuth; switch (fnType->getRepresentation()) { + case SILFunctionTypeRepresentation::CXXMethod: case SILFunctionTypeRepresentation::CFunctionPointer: return options.FunctionPointers; @@ -583,6 +584,7 @@ PointerAuthEntity::getTypeDiscriminator(IRGenModule &IGM) const { } // C function pointers are undiscriminated. + case SILFunctionTypeRepresentation::CXXMethod: case SILFunctionTypeRepresentation::CFunctionPointer: return llvm::ConstantInt::get(IGM.Int64Ty, 0); diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index f7faa8febd0da..38ae13487167b 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -2321,6 +2321,7 @@ bool irgen::hasPolymorphicParameters(CanSILFunctionType ty) { case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::ObjCMethod: + case SILFunctionTypeRepresentation::CXXMethod: // May be polymorphic at the SIL level, but no type metadata is actually // passed. return false; diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index d2076c41bfbb1..9c93c69fff56a 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -2930,6 +2930,7 @@ Callee LoweredValue::getCallee(IRGenFunction &IGF, return getBlockPointerCallee(IGF, functionValue, std::move(calleeInfo)); case SILFunctionType::Representation::ObjCMethod: + case SILFunctionType::Representation::CXXMethod: case SILFunctionType::Representation::Thick: llvm_unreachable("unexpected function with singleton representation"); @@ -2991,6 +2992,7 @@ static std::unique_ptr getCallEmissionForLoweredValue( } case SILFunctionType::Representation::ObjCMethod: + case SILFunctionType::Representation::CXXMethod: case SILFunctionType::Representation::Thick: case SILFunctionType::Representation::Block: case SILFunctionType::Representation::Thin: @@ -3363,6 +3365,7 @@ getPartialApplicationFunction(IRGenSILFunction &IGF, SILValue v, case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::Block: case SILFunctionTypeRepresentation::ObjCMethod: + case SILFunctionTypeRepresentation::CXXMethod: llvm_unreachable("partial_apply of foreign functions not implemented"); case SILFunctionTypeRepresentation::WitnessMethod: diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp index fe227670426be..2178aea84b89a 100644 --- a/lib/IRGen/MetadataRequest.cpp +++ b/lib/IRGen/MetadataRequest.cpp @@ -3027,6 +3027,7 @@ class EmitTypeMetadataRefForLayout case SILFunctionType::Representation::Method: case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::ObjCMethod: + case SILFunctionType::Representation::CXXMethod: case SILFunctionType::Representation::CFunctionPointer: case SILFunctionType::Representation::Closure: // A thin function looks like a plain pointer. @@ -3230,6 +3231,7 @@ namespace { case SILFunctionType::Representation::Method: case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::ObjCMethod: + case SILFunctionType::Representation::CXXMethod: case SILFunctionType::Representation::CFunctionPointer: case SILFunctionType::Representation::Closure: // A thin function looks like a plain pointer. diff --git a/lib/SIL/IR/Bridging.cpp b/lib/SIL/IR/Bridging.cpp index 6f89d9839679c..7dac4efc52ba0 100644 --- a/lib/SIL/IR/Bridging.cpp +++ b/lib/SIL/IR/Bridging.cpp @@ -106,6 +106,7 @@ Type TypeConverter::getLoweredBridgedType(AbstractionPattern pattern, case SILFunctionTypeRepresentation::CFunctionPointer: case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::Block: + case SILFunctionTypeRepresentation::CXXMethod: // Map native types back to bridged types. // Look through optional types. @@ -177,13 +178,12 @@ Type TypeConverter::getLoweredCBridgedType(AbstractionPattern pattern, if (auto funTy = t->getAs()) { switch (funTy->getExtInfo().getSILRepresentation()) { - // Functions that are already represented as blocks or C function pointers - // don't need bridging. case SILFunctionType::Representation::Block: case SILFunctionType::Representation::CFunctionPointer: case SILFunctionType::Representation::Thin: case SILFunctionType::Representation::Method: case SILFunctionType::Representation::ObjCMethod: + case SILFunctionTypeRepresentation::CXXMethod: case SILFunctionType::Representation::WitnessMethod: case SILFunctionType::Representation::Closure: return t; diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index e0f2bfb61663b..835528d820ef4 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -2303,6 +2303,7 @@ static CanSILFunctionType getNativeSILFunctionType( switch (extInfoBuilder.getRepresentation()) { case SILFunctionType::Representation::Block: case SILFunctionType::Representation::CFunctionPointer: + case SILFunctionTypeRepresentation::CXXMethod: return getSILFunctionTypeForAbstractCFunction( TC, origType, substInterfaceType, extInfoBuilder, constant); @@ -3127,8 +3128,26 @@ SILFunctionTypeRepresentation TypeConverter::getDeclRefRepresentation(SILDeclRef c) { // If this is a foreign thunk, it always has the foreign calling convention. if (c.isForeign) { - if (!c.hasDecl() || - c.getDecl()->isImportAsMember()) + if (!c.hasDecl()) + return SILFunctionTypeRepresentation::CFunctionPointer; + + // TODO: Is this correct for operators? + if (auto method = + dyn_cast_or_null(c.getDecl()->getClangDecl())) { + // Subscripts and call operators are imported as normal methods. + bool staticOperator = method->isOverloadedOperator() && + method->getOverloadedOperator() != clang::OO_Call && + method->getOverloadedOperator() != clang::OO_Subscript; + return isa(method) || + method->isStatic() || + staticOperator + ? SILFunctionTypeRepresentation::CFunctionPointer + : SILFunctionTypeRepresentation::CXXMethod; + } + + + // For example, if we have a function in a namespace: + if (c.getDecl()->isImportAsMember()) return SILFunctionTypeRepresentation::CFunctionPointer; if (isObjCMethod(c.getDecl()) || @@ -4137,6 +4156,7 @@ TypeConverter::getLoweredFormalTypes(SILDeclRef constant, bridgedResultType = resultType; break; + case SILFunctionTypeRepresentation::CXXMethod: case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::CFunctionPointer: { if (rep == SILFunctionTypeRepresentation::ObjCMethod) { diff --git a/lib/SIL/Utils/InstructionUtils.cpp b/lib/SIL/Utils/InstructionUtils.cpp index f96b27c2c862f..bb1de76dcdf2b 100644 --- a/lib/SIL/Utils/InstructionUtils.cpp +++ b/lib/SIL/Utils/InstructionUtils.cpp @@ -776,6 +776,7 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType) rt |= RuntimeEffect::MetaData; break; case SILFunctionTypeRepresentation::CFunctionPointer: + case SILFunctionTypeRepresentation::CXXMethod: case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Method: case SILFunctionTypeRepresentation::Closure: diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index 21ae0b0791a34..45d9840d9dd43 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -1671,6 +1671,7 @@ static ManagedValue convertFunctionRepresentation(SILGenFunction &SGF, case SILFunctionType::Representation::Closure: case SILFunctionType::Representation::ObjCMethod: case SILFunctionType::Representation::WitnessMethod: + case SILFunctionType::Representation::CXXMethod: llvm_unreachable("should not do function conversion from method rep"); } llvm_unreachable("bad representation"); @@ -1700,6 +1701,7 @@ static ManagedValue convertFunctionRepresentation(SILGenFunction &SGF, case SILFunctionType::Representation::Closure: case SILFunctionType::Representation::ObjCMethod: case SILFunctionType::Representation::WitnessMethod: + case SILFunctionType::Representation::CXXMethod: llvm_unreachable("should not do function conversion from method rep"); } llvm_unreachable("bad representation"); diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp index 62c47e04629a8..a044e6c57447f 100644 --- a/lib/SILGen/SILGenPoly.cpp +++ b/lib/SILGen/SILGenPoly.cpp @@ -4718,6 +4718,17 @@ void SILGenFunction::emitProtocolWitness(AbstractionPattern reqtOrigTy, witnessUnsubstTy->getSelfParameter()); } + // For static C++ methods and constructors, we need to drop the (metatype) + // "self" param. The "native" SIL representation will look like this: + // @convention(method) (@thin Foo.Type) -> () but the "actual" SIL function + // looks like this: + // @convention(c) () -> () + // . We do this by simply omiting the last params. + // TODO: fix this for static C++ methods. + if (witness.getDecl()->getClangDecl() && + isa(witness.getDecl()->getClangDecl())) + reqtSubstParams = reqtSubstParams.drop_back(); + // For a free function witness, discard the 'self' parameter of the // requirement. if (isFree) { diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp index 1f095a281ba16..08f2af1512c12 100644 --- a/lib/SILGen/SILGenType.cpp +++ b/lib/SILGen/SILGenType.cpp @@ -415,8 +415,19 @@ template class SILGenWitnessTable : public SILWitnessVisitor { // If it's not an accessor, just look for the witness. if (!reqAccessor) { if (auto witness = asDerived().getWitness(reqDecl)) { + auto newDecl = requirementRef.withDecl(witness.getDecl()); + // Only import C++ methods as foreign. If the following + // Objective-C function is imported as foreign: + // () -> String + // It will be imported as the following type: + // () -> NSString + // But the first is correct, so make sure we don't mark this witness + // as foreign. + if (dyn_cast_or_null( + witness.getDecl()->getClangDecl())) + newDecl = newDecl.asForeign(); return addMethodImplementation( - requirementRef, getWitnessRef(requirementRef, witness), + requirementRef, getWitnessRef(newDecl, witness), witness); } diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp index 5e7c98db5d7e8..8857f2d8aac7c 100644 --- a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp +++ b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp @@ -84,6 +84,7 @@ static bool isSpecializableRepresentation(SILFunctionTypeRepresentation Rep, case SILFunctionTypeRepresentation::Thin: case SILFunctionTypeRepresentation::Thick: case SILFunctionTypeRepresentation::CFunctionPointer: + case SILFunctionTypeRepresentation::CXXMethod: return true; case SILFunctionTypeRepresentation::WitnessMethod: return OptForPartialApply; diff --git a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp index 6ed8c1cf65e3f..398e84d0d6fc2 100644 --- a/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp +++ b/lib/SILOptimizer/Mandatory/MandatoryInlining.cpp @@ -714,6 +714,7 @@ getCalleeFunction(SILFunction *F, FullApplySite AI, bool &IsThick, break; case SILFunctionTypeRepresentation::CFunctionPointer: + case SILFunctionTypeRepresentation::CXXMethod: case SILFunctionTypeRepresentation::ObjCMethod: case SILFunctionTypeRepresentation::Block: return nullptr; diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index 8742dd2f73d67..88bc807c1c7e4 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -269,12 +269,13 @@ enum class SILFunctionTypeRepresentation : uint8_t { Block, Thin, CFunctionPointer, - + FirstSIL = 8, Method = FirstSIL, ObjCMethod, WitnessMethod, Closure, + CXXMethod, }; using SILFunctionTypeRepresentationField = BCFixed<4>; diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 78efa6e365e8c..e478641c18706 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -4176,6 +4176,7 @@ static uint8_t getRawStableSILFunctionTypeRepresentation( SIMPLE_CASE(SILFunctionTypeRepresentation, ObjCMethod) SIMPLE_CASE(SILFunctionTypeRepresentation, WitnessMethod) SIMPLE_CASE(SILFunctionTypeRepresentation, Closure) + SIMPLE_CASE(SILFunctionTypeRepresentation, CXXMethod) } llvm_unreachable("bad calling convention"); } diff --git a/test/Interop/Cxx/class/Inputs/protocol-conformance.h b/test/Interop/Cxx/class/Inputs/protocol-conformance.h index 241f89ff1de58..18da7c2575db2 100644 --- a/test/Interop/Cxx/class/Inputs/protocol-conformance.h +++ b/test/Interop/Cxx/class/Inputs/protocol-conformance.h @@ -9,4 +9,23 @@ struct DoesNotConformToProtocol { int returnFortyTwo() { return 42; } }; -#endif // TEST_INTEROP_CXX_CLASS_INPUTS_PROTOCOL_CONFORMANCE_H +struct DummyStruct {}; + +struct NonTrivial { + ~NonTrivial() {} + NonTrivial(DummyStruct) {} + NonTrivial() {} + void test1() {} + void test2(int) {} + char test3(int, unsigned) { return 42; } +}; + +struct Trivial { + Trivial(DummyStruct) {} + Trivial() {} + void test1() {} + void test2(int) {} + char test3(int, unsigned) { return 42; } +}; + +#endif // TEST_INTEROP_CXX_CLASS_INPUTS_PROTOCOL_CONFORMANCE_H \ No newline at end of file diff --git a/test/Interop/Cxx/class/protocol-conformance-irgen.swift b/test/Interop/Cxx/class/protocol-conformance-irgen.swift new file mode 100644 index 0000000000000..c7f904e602d6d --- /dev/null +++ b/test/Interop/Cxx/class/protocol-conformance-irgen.swift @@ -0,0 +1,19 @@ +// RUN: %target-swift-emit-ir -I %S/Inputs -enable-cxx-interop %s | %FileCheck %s + +import ProtocolConformance + +protocol HasReturn42 { + mutating func return42() -> CInt +} + + +// CHECK: define {{.*}}i32 @"$sSo18ConformsToProtocolV4main11HasReturn42A2cDP8return42s5Int32VyFTW"(%TSo18ConformsToProtocolV* nocapture swiftself dereferenceable(1) %{{.*}}, %swift.type* %{{.*}}, i8** %{{.*}}) +// CHECK: [[OUT:%.*]] = call i32 @{{_ZN18ConformsToProtocol8return42Ev|"\?return42@ConformsToProtocol@@QEAAHXZ"}}(%struct.ConformsToProtocol* +// CHECK: ret i32 [[OUT]] + +// CHECK: define {{.*}}%swift.metadata_response @"$sSo18ConformsToProtocolVMa"(i64 [[ARG:%.*]]) +// CHECK: load %swift.type*, %swift.type** @"$sSo18ConformsToProtocolVML" +// CHECK: call swiftcc %swift.metadata_response @swift_getForeignTypeMetadata(i64 [[ARG]], %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, i64, <{ i32, i32, i32, i32, i32, i32, i32, i32 }>* }>* @"$sSo18ConformsToProtocolVMf" to %swift.full_type*), i32 0, i32 1)) +// CHECK: ret %swift.metadata_response + +extension ConformsToProtocol : HasReturn42 {} diff --git a/test/Interop/Cxx/class/protocol-conformance-silgen.swift b/test/Interop/Cxx/class/protocol-conformance-silgen.swift index 951f10a0b9ca6..0eb034d3ded0a 100644 --- a/test/Interop/Cxx/class/protocol-conformance-silgen.swift +++ b/test/Interop/Cxx/class/protocol-conformance-silgen.swift @@ -1,6 +1,6 @@ // Tests that a C++ class can conform to a Swift protocol. -// RUN: %target-swift-emit-silgen -I %S/Inputs -enable-cxx-interop %s +// RUN: %target-swift-emit-silgen -I %S/Inputs -enable-cxx-interop %s | %FileCheck %s import ProtocolConformance @@ -8,8 +8,11 @@ protocol HasReturn42 { mutating func return42() -> CInt } -// FIXME: -// https://bugs.swift.org/browse/SR-12750 -// SILGen currently hits an assertion failure in getParameterTypes() when the -// following protocol conformance is declared. -// extension ConformsToProtocol : HasReturn42 {} +// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$sSo18ConformsToProtocolV4main11HasReturn42A2cDP8return42s5Int32VyFTW : $@convention(witness_method: HasReturn42) (@inout ConformsToProtocol) -> Int32 +// CHECK: bb0([[ARG:%.*]] : $*ConformsToProtocol): +// CHECK: [[FN:%.*]] = function_ref @[[FN_NAME:.*]] : $@convention(cxx_method) (@inout ConformsToProtocol) -> Int32 +// CHECK: [[OUT:%.*]] = apply %1(%0) : $@convention(cxx_method) (@inout ConformsToProtocol) -> Int32 +// CHECK: return [[OUT]] : $Int32 + +// sil [clang ConformsToProtocol.return42] @[[FN_NAME]] : $@convention(c) (@inout ConformsToProtocol) -> Int32 +extension ConformsToProtocol : HasReturn42 {} diff --git a/test/Interop/Cxx/class/protocol-conformance.swift b/test/Interop/Cxx/class/protocol-conformance.swift new file mode 100644 index 0000000000000..0fda5d2749fca --- /dev/null +++ b/test/Interop/Cxx/class/protocol-conformance.swift @@ -0,0 +1,104 @@ +// RUN: %target-run-simple-swift(-I %S/Inputs/ -Xfrontend -enable-cxx-interop) + +// REQUIRES: executable_test + +import StdlibUnittest +import ProtocolConformance + +protocol TestMethods { + init(_: DummyStruct) + mutating func test1() + mutating func test2(_: Int32) + mutating func test3(_: Int32, _: UInt32) -> CChar +} + +protocol CanReturn42 { + mutating func return42() -> Int32 +} + +extension CanReturn42 { + mutating func return42() -> Int32 { 0 } +} + +protocol DefaultInitializable { + init() +} + +extension NonTrivial : TestMethods { } +extension NonTrivial : DefaultInitializable { } + +extension Trivial : TestMethods { } +extension Trivial : DefaultInitializable { } + +extension Trivial : CanReturn42 { } +extension ConformsToProtocol : CanReturn42 { } + +@inline(never) +@_optimize(none) +func tryReturn42(_ _p: CanReturn42) -> Int32 { + var p = _p + return p.return42() +} + +@inline(never) +@_optimize(none) +func makeIt(_ _: T.Type) -> T { T() } + +@inline(never) +@_optimize(none) +func makeItWithDummy(_ _: T.Type) -> T { T(DummyStruct()) } + +@inline(never) +@_optimize(none) +func callTestMethods(on _subject: TestMethods) -> CChar { + var subject = _subject + subject.test1() + subject.test2(0 as Int32) + return subject.test3(0 as Int32, 1 as UInt32) +} + +struct Holder { + var value: DefaultInitializable & TestMethods = T() +} + +@inline(never) +@_optimize(none) +func callTestMethods(on subject: Holder) -> CChar { + callTestMethods(on: subject.value) +} + +var ExtendedTypes = TestSuite("Extended C++ Types") + +ExtendedTypes.test("(Don't) Use default impl") { + let noMethod = Trivial() + expectEqual(0, tryReturn42(noMethod)) + + let hasMethod = ConformsToProtocol() + expectEqual(42, tryReturn42(hasMethod)) +} + +ExtendedTypes.test("Constrained generic") { + var trivial = makeIt(Trivial.self) + var result = callTestMethods(on: trivial) + expectEqual(42, result) + + let nonTrivial = makeIt(NonTrivial.self) + result = callTestMethods(on: nonTrivial) + expectEqual(42, result) + + trivial = makeItWithDummy(Trivial.self) + result = callTestMethods(on: trivial) + expectEqual(42, result) +} + +ExtendedTypes.test("Generic struct") { + var hold = Holder() + var result = callTestMethods(on: hold) + expectEqual(42, result) + + hold.value = makeItWithDummy(NonTrivial.self) + result = callTestMethods(on: hold) + expectEqual(42, result) +} + +runAllTests() diff --git a/test/Interop/Cxx/foreign-reference/move-only-silgen.swift b/test/Interop/Cxx/foreign-reference/move-only-silgen.swift index e56ce3098a0a0..bd6ea4ad0c382 100644 --- a/test/Interop/Cxx/foreign-reference/move-only-silgen.swift +++ b/test/Interop/Cxx/foreign-reference/move-only-silgen.swift @@ -18,8 +18,8 @@ import MoveOnly // CHECK: [[TMP:%.*]] = alloc_stack $MoveOnly // CHECK: store [[X_1]] to [trivial] [[TMP]] -// CHECK: [[TEST_FN:%.*]] = function_ref @{{_ZNK8MoveOnly4testEv|\?test\@MoveOnly\@\@QEBAHXZ}} : $@convention(c) (@in_guaranteed MoveOnly) -> Int32 -// CHECK: apply [[TEST_FN]]([[TMP]]) : $@convention(c) (@in_guaranteed MoveOnly) -> Int32 +// CHECK: [[TEST_FN:%.*]] = function_ref @{{_ZNK8MoveOnly4testEv|\?test\@MoveOnly\@\@QEBAHXZ}} : $@convention(cxx_method) (@in_guaranteed MoveOnly) -> Int32 +// CHECK: apply [[TEST_FN]]([[TMP]]) : $@convention(cxx_method) (@in_guaranteed MoveOnly) -> Int32 // CHECK: return // CHECK-LABEL: end sil function '$s4main4testyyF' @@ -30,4 +30,4 @@ public func test() { // CHECK-LABEL: sil [clang MoveOnly.create] @{{_ZN8MoveOnly6createEv|\?create\@MoveOnly\@\@SAPEAU1\@XZ}} : $@convention(c) () -> MoveOnly -// CHECK-LABEL: sil [clang MoveOnly.test] @{{_ZNK8MoveOnly4testEv|\?test\@MoveOnly\@\@QEBAHXZ}} : $@convention(c) (@in_guaranteed MoveOnly) -> Int32 +// CHECK-LABEL: sil [clang MoveOnly.test] @{{_ZNK8MoveOnly4testEv|\?test\@MoveOnly\@\@QEBAHXZ}} : $@convention(cxx_method) (@in_guaranteed MoveOnly) -> Int32 diff --git a/test/Interop/Cxx/foreign-reference/pod-silgen.swift b/test/Interop/Cxx/foreign-reference/pod-silgen.swift index bf7192f2dc40b..ea4546d1dbbbc 100644 --- a/test/Interop/Cxx/foreign-reference/pod-silgen.swift +++ b/test/Interop/Cxx/foreign-reference/pod-silgen.swift @@ -23,8 +23,8 @@ import POD // CHECK: [[X_2:%.*]] = load [trivial] [[ACCESS_3]] : $*IntPair // CHECK: [[TMP:%.*]] = alloc_stack $IntPair // CHECK: store [[X_2]] to [trivial] [[TMP]] -// CHECK: [[TEST_FN:%.*]] = function_ref @{{_ZNK7IntPair4testEv|\?test\@IntPair\@\@QEBAHXZ}} : $@convention(c) (@in_guaranteed IntPair) -> Int32 -// CHECK: apply [[TEST_FN]]([[TMP]]) : $@convention(c) (@in_guaranteed IntPair) -> Int32 +// CHECK: [[TEST_FN:%.*]] = function_ref @{{_ZNK7IntPair4testEv|\?test\@IntPair\@\@QEBAHXZ}} : $@convention(cxx_method) (@in_guaranteed IntPair) -> Int32 +// CHECK: apply [[TEST_FN]]([[TMP]]) : $@convention(cxx_method) (@in_guaranteed IntPair) -> Int32 // CHECK: return // CHECK-LABEL: end sil function '$s4main4testyyF' @@ -36,4 +36,4 @@ public func test() { // CHECK-LABEL: sil [clang IntPair.create] @{{_ZN7IntPair6createEv|\?create\@IntPair\@\@SAPEAU1\@XZ}} : $@convention(c) () -> IntPair -// CHECK-LABEL: sil [clang IntPair.test] @{{_ZNK7IntPair4testEv|\?test\@IntPair\@\@QEBAHXZ}} : $@convention(c) (@in_guaranteed IntPair) -> Int32 +// CHECK-LABEL: sil [clang IntPair.test] @{{_ZNK7IntPair4testEv|\?test\@IntPair\@\@QEBAHXZ}} : $@convention(cxx_method) (@in_guaranteed IntPair) -> Int32 diff --git a/test/Interop/Cxx/foreign-reference/singleton-silgen.swift b/test/Interop/Cxx/foreign-reference/singleton-silgen.swift index f9353a56f7fda..f5f68edbf2f08 100644 --- a/test/Interop/Cxx/foreign-reference/singleton-silgen.swift +++ b/test/Interop/Cxx/foreign-reference/singleton-silgen.swift @@ -18,8 +18,8 @@ import Singleton // CHECK: [[TMP:%.*]] = alloc_stack $DeletedSpecialMembers // CHECK: store [[X_1]] to [trivial] [[TMP]] -// CHECK: [[TEST_FN:%.*]] = function_ref @{{_ZNK21DeletedSpecialMembers4testEv|\?test\@DeletedSpecialMembers\@\@QEBAHXZ}} : $@convention(c) (@in_guaranteed DeletedSpecialMembers) -> Int32 -// CHECK: apply [[TEST_FN]]([[TMP]]) : $@convention(c) (@in_guaranteed DeletedSpecialMembers) -> Int32 +// CHECK: [[TEST_FN:%.*]] = function_ref @{{_ZNK21DeletedSpecialMembers4testEv|\?test\@DeletedSpecialMembers\@\@QEBAHXZ}} : $@convention(cxx_method) (@in_guaranteed DeletedSpecialMembers) -> Int32 +// CHECK: apply [[TEST_FN]]([[TMP]]) : $@convention(cxx_method) (@in_guaranteed DeletedSpecialMembers) -> Int32 // CHECK: [[ACCESS_2:%.*]] = begin_access [read] [unknown] [[BOX]] : $*DeletedSpecialMembers // CHECK: [[X_2:%.*]] = load [trivial] [[ACCESS_2]] : $*DeletedSpecialMembers @@ -36,6 +36,6 @@ public func test() { // CHECK-LABEL: sil [clang DeletedSpecialMembers.create] @{{_ZN21DeletedSpecialMembers6createEv|\?create\@DeletedSpecialMembers\@\@SAPEAU1\@XZ}} : $@convention(c) () -> DeletedSpecialMembers -// CHECK-LABEL: sil [clang DeletedSpecialMembers.test] @{{_ZNK21DeletedSpecialMembers4testEv|\?test\@DeletedSpecialMembers\@\@QEBAHXZ}} : $@convention(c) (@in_guaranteed DeletedSpecialMembers) -> Int32 +// CHECK-LABEL: sil [clang DeletedSpecialMembers.test] @{{_ZNK21DeletedSpecialMembers4testEv|\?test\@DeletedSpecialMembers\@\@QEBAHXZ}} : $@convention(cxx_method) (@in_guaranteed DeletedSpecialMembers) -> Int32 // CHECK-LABEL: sil [serializable] [clang mutateIt] @{{_Z8mutateItR21DeletedSpecialMembers|\?mutateIt\@\@YAXAEAUDeletedSpecialMembers\@\@\@Z}} : $@convention(c) (DeletedSpecialMembers) -> () diff --git a/test/Interop/Cxx/operators/member-inline-silgen.swift b/test/Interop/Cxx/operators/member-inline-silgen.swift index ec6d5a888c6b0..1a1269918abb3 100644 --- a/test/Interop/Cxx/operators/member-inline-silgen.swift +++ b/test/Interop/Cxx/operators/member-inline-silgen.swift @@ -17,34 +17,34 @@ public func call(_ wrapper: inout LoadableIntWrapper, _ arg: Int32) -> Int32 { w // CHECK: bb0([[SELF:%.*]] : $*LoadableIntWrapper, [[RHS:%.*]] : $Int32): // CHECK: [[SELFACCESS:%.*]] = begin_access [modify] [static] [[SELF]] : $*LoadableIntWrapper -// CHECK: [[OP:%.*]] = function_ref [[NAME:@(_ZN18LoadableIntWrapperclEi|\?\?RLoadableIntWrapper@@QEAAHH@Z)]] : $@convention(c) (@inout LoadableIntWrapper, Int32) -> Int32 -// CHECK: apply [[OP]]([[SELFACCESS]], [[RHS]]) : $@convention(c) (@inout LoadableIntWrapper, Int32) -> Int32 +// CHECK: [[OP:%.*]] = function_ref [[NAME:@(_ZN18LoadableIntWrapperclEi|\?\?RLoadableIntWrapper@@QEAAHH@Z)]] : $@convention(cxx_method) (Int32, @inout LoadableIntWrapper) -> Int32 +// CHECK: apply [[OP]]([[RHS]], [[SELFACCESS]]) : $@convention(cxx_method) (Int32, @inout LoadableIntWrapper) -> Int32 // CHECK: end_access [[SELFACCESS]] : $*LoadableIntWrapper -// CHECK: sil [clang LoadableIntWrapper.callAsFunction] [[NAME]] : $@convention(c) (@inout LoadableIntWrapper, Int32) -> Int32 +// CHECK: sil [clang LoadableIntWrapper.callAsFunction] [[NAME]] : $@convention(cxx_method) (Int32, @inout LoadableIntWrapper) -> Int32 public func call(_ wrapper: inout AddressOnlyIntWrapper) -> Int32 { wrapper() } // CHECK: bb0([[SELF:%.*]] : $*AddressOnlyIntWrapper): // CHECK: [[SELFACCESS:%.*]] = begin_access [modify] [static] [[SELF]] : $*AddressOnlyIntWrapper -// CHECK: [[OP:%.*]] = function_ref [[NAME:@(_ZN21AddressOnlyIntWrapperclEv|\?\?RAddressOnlyIntWrapper@@QEAAHXZ)]] : $@convention(c) (@inout AddressOnlyIntWrapper) -> Int32 -// CHECK: apply [[OP]]([[SELFACCESS]]) : $@convention(c) (@inout AddressOnlyIntWrapper) -> Int32 +// CHECK: [[OP:%.*]] = function_ref [[NAME:@(_ZN21AddressOnlyIntWrapperclEv|\?\?RAddressOnlyIntWrapper@@QEAAHXZ)]] : $@convention(cxx_method) (@inout AddressOnlyIntWrapper) -> Int32 +// CHECK: apply [[OP]]([[SELFACCESS]]) : $@convention(cxx_method) (@inout AddressOnlyIntWrapper) -> Int32 // CHECK: end_access [[SELFACCESS]] : $*AddressOnlyIntWrapper -// CHECK: sil [clang AddressOnlyIntWrapper.callAsFunction] [[NAME]] : $@convention(c) (@inout AddressOnlyIntWrapper) -> Int32 +// CHECK: sil [clang AddressOnlyIntWrapper.callAsFunction] [[NAME]] : $@convention(cxx_method) (@inout AddressOnlyIntWrapper) -> Int32 public func index(_ arr: ReadOnlyIntArray, _ arg: Int32) -> Int32 { arr[arg] } // CHECK: sil @$s4main5indexys5Int32VSo16ReadOnlyIntArrayV_ADtF : $@convention(thin) (@in_guaranteed ReadOnlyIntArray, Int32) -> Int32 { // CHECK: bb0([[ARR:%.*]] : $*ReadOnlyIntArray, [[INDEX:%.*]] : $Int32): -// CHECK: [[OP:%.*]] = function_ref [[READCLASSNAME:@(_ZNK16ReadOnlyIntArrayixEi|\?\?AReadOnlyIntArray@@QEBAAEBHH@Z)]] : $@convention(c) (@in ReadOnlyIntArray, Int32) -> UnsafePointer -// CHECK: [[PTR:%.*]] = apply [[OP]]([[ARRACCESS:%.*]], [[INDEX]]) : $@convention(c) (@in ReadOnlyIntArray, Int32) -> UnsafePointer +// CHECK: [[OP:%.*]] = function_ref [[READCLASSNAME:@(_ZNK16ReadOnlyIntArrayixEi|\?\?AReadOnlyIntArray@@QEBAAEBHH@Z)]] : $@convention(cxx_method) (Int32, @in_guaranteed ReadOnlyIntArray) -> UnsafePointer +// CHECK: [[PTR:%.*]] = apply [[OP]]([[INDEX]], [[ARRACCESS:%.*]]) : $@convention(cxx_method) (Int32, @in_guaranteed ReadOnlyIntArray) -> UnsafePointer // CHECK: } // end sil function '$s4main5indexys5Int32VSo16ReadOnlyIntArrayV_ADtF' // CHECK: sil shared [transparent] @$sSo16ReadOnlyIntArrayVys5Int32VADcig : $@convention(method) (Int32, @in_guaranteed ReadOnlyIntArray) -> Int32 { // CHECK: bb0([[INDEX:%.*]] : $Int32, [[SELF:%.*]] : $*ReadOnlyIntArray): -// CHECK: [[OP:%.*]] = function_ref [[READCLASSNAME]] : $@convention(c) (@in ReadOnlyIntArray, Int32) -> UnsafePointer -// CHECK: [[PTR:%.*]] = apply [[OP]]([[SELFACCESS:%.*]], [[INDEX]]) : $@convention(c) (@in ReadOnlyIntArray, Int32) -> UnsafePointer +// CHECK: [[OP:%.*]] = function_ref [[READCLASSNAME]] : $@convention(cxx_method) (Int32, @in_guaranteed ReadOnlyIntArray) -> UnsafePointer +// CHECK: [[PTR:%.*]] = apply [[OP]]([[INDEX]], [[SELFACCESS:%.*]]) : $@convention(cxx_method) (Int32, @in_guaranteed ReadOnlyIntArray) -> UnsafePointer // CHECK: [[PTR2:%.*]] = struct_extract [[PTR]] : $UnsafePointer, #UnsafePointer._rawValue // CHECK: pointer_to_address [[PTR2]] : $Builtin.RawPointer to [strict] $*Int32 // CHECK: } // end sil function '$sSo16ReadOnlyIntArrayVys5Int32VADcig' @@ -55,15 +55,15 @@ public func index(_ arr: inout ReadWriteIntArray, _ arg: Int32, _ val: Int32) { // CHECK: bb0([[ARR:%.*]] : $*ReadWriteIntArray, [[INDEX:%.*]] : $Int32, [[NEWVALUE:%.*]] : $Int32): // CHECK: [[ARRACCESS:%.*]] = begin_access [modify] [static] [[ARR]] : $*ReadWriteIntArray // CHECK: [[ARRACCESS2:%.*]] = begin_access [modify] [static] [[ARRACCESS]] : $*ReadWriteIntArray -// CHECK: [[OP:%.*]] = function_ref [[READWRITECLASSNAME:@(_ZN17ReadWriteIntArrayixEi|\?\?AReadWriteIntArray@@QEAAAEAHH@Z)]] : $@convention(c) (@inout ReadWriteIntArray, Int32) -> UnsafeMutablePointer -// CHECK: [[PTR:%.*]] = apply [[OP]]([[ARRACCESS2]], [[INDEX]]) : $@convention(c) (@inout ReadWriteIntArray, Int32) -> UnsafeMutablePointer +// CHECK: [[OP:%.*]] = function_ref [[READWRITECLASSNAME:@(_ZN17ReadWriteIntArrayixEi|\?\?AReadWriteIntArray@@QEAAAEAHH@Z)]] : $@convention(cxx_method) (Int32, @inout ReadWriteIntArray) -> UnsafeMutablePointer +// CHECK: [[PTR:%.*]] = apply [[OP]]([[INDEX]], [[ARRACCESS2]]) : $@convention(cxx_method) (Int32, @inout ReadWriteIntArray) -> UnsafeMutablePointer // CHECK: } // end sil function '$s4main5indexyySo17ReadWriteIntArrayVz_s5Int32VAFtF' // CHECK: sil shared [transparent] @$sSo17ReadWriteIntArrayVys5Int32VADcis : $@convention(method) (Int32, Int32, @inout ReadWriteIntArray) -> () { // CHECK: bb0([[NEWVALUE:%.*]] : $Int32, [[INDEX:%.*]] : $Int32, [[SELF:%.*]] : $*ReadWriteIntArray): // CHECK: [[SELFACCESS:%.*]] = begin_access [modify] [static] [[SELF]] : $*ReadWriteIntArray -// CHECK: [[OP:%.*]] = function_ref [[READWRITECLASSNAME]] : $@convention(c) (@inout ReadWriteIntArray, Int32) -> UnsafeMutablePointer -// CHECK: [[PTR:%.*]] = apply [[OP]]([[SELFACCESS]], [[INDEX]]) : $@convention(c) (@inout ReadWriteIntArray, Int32) -> UnsafeMutablePointer +// CHECK: [[OP:%.*]] = function_ref [[READWRITECLASSNAME]] : $@convention(cxx_method) (Int32, @inout ReadWriteIntArray) -> UnsafeMutablePointer +// CHECK: [[PTR:%.*]] = apply [[OP]]([[INDEX]], [[SELFACCESS]]) : $@convention(cxx_method) (Int32, @inout ReadWriteIntArray) -> UnsafeMutablePointer // CHECK: end_access [[SELFACCESS]] : $*ReadWriteIntArray // CHECK: [[PTR2:%.*]] = struct_extract [[PTR]] : $UnsafeMutablePointer, #UnsafeMutablePointer._rawValue // CHECK: pointer_to_address [[PTR2]] : $Builtin.RawPointer to [strict] $*Int32 @@ -73,14 +73,14 @@ public func index(_ arr: inout NonTrivialIntArrayByVal, _ arg: Int32, _ val: Int // CHECK: sil @$s4main5indexys5Int32VSo23NonTrivialIntArrayByValVz_A2DtF : $@convention(thin) (@inout NonTrivialIntArrayByVal, Int32, Int32) -> Int32 { // CHECK: bb0([[ARR:%.*]] : $*NonTrivialIntArrayByVal, [[INDEX:%.*]] : $Int32, [[NEWVALUE:%.*]] : $Int32): -// CHECK: [[OP:%.*]] = function_ref [[READWRITECLASSNAMEBYVAL:@(_ZNK23NonTrivialIntArrayByValixEi|\?\?ANonTrivialIntArrayByVal@@QEBAHH@Z)]] : $@convention(c) (@in NonTrivialIntArrayByVal, Int32) -> Int32 -// CHECK: [[PTR:%.*]] = apply [[OP]]([[ARRACCESS:%.*]], [[INDEX]]) : $@convention(c) (@in NonTrivialIntArrayByVal, Int32) -> Int32 +// CHECK: [[OP:%.*]] = function_ref [[READWRITECLASSNAMEBYVAL:@(_ZNK23NonTrivialIntArrayByValixEi|\?\?ANonTrivialIntArrayByVal@@QEBAHH@Z)]] : $@convention(cxx_method) (Int32, @in_guaranteed NonTrivialIntArrayByVal) -> Int32 +// CHECK: [[PTR:%.*]] = apply [[OP]]([[INDEX]], [[ARRACCESS:%.*]]) : $@convention(cxx_method) (Int32, @in_guaranteed NonTrivialIntArrayByVal) -> Int32 // CHECK: } // end sil function '$s4main5indexys5Int32VSo23NonTrivialIntArrayByValVz_A2DtF' // CHECK: sil shared [transparent] @$sSo23NonTrivialIntArrayByValVys5Int32VADcig : $@convention(method) (Int32, @in_guaranteed NonTrivialIntArrayByVal) -> Int32 { // CHECK: bb0([[NEWVALUE:%.*]] : $Int32, [[INDEX:%.*]] : $*NonTrivialIntArrayByVal): -// CHECK: [[OP:%.*]] = function_ref [[READWRITECLASSNAMEBYVAL]] : $@convention(c) (@in NonTrivialIntArrayByVal, Int32) -> Int32 -// CHECK: [[PTR:%.*]] = apply [[OP]]([[SELFACCESS:%.*]], [[NEWVALUE]]) : $@convention(c) (@in NonTrivialIntArrayByVal, Int32) -> Int32 +// CHECK: [[OP:%.*]] = function_ref [[READWRITECLASSNAMEBYVAL]] : $@convention(cxx_method) (Int32, @in_guaranteed NonTrivialIntArrayByVal) -> Int32 +// CHECK: [[PTR:%.*]] = apply [[OP]]([[NEWVALUE]], [[SELFACCESS:%.*]]) : $@convention(cxx_method) (Int32, @in_guaranteed NonTrivialIntArrayByVal) -> Int32 // CHECK: } // end sil function '$sSo23NonTrivialIntArrayByValVys5Int32VADcig public func index(_ arr: inout PtrByVal, _ arg: Int32, _ val: Int32) -> Int32 { arr[arg]![0] } @@ -88,15 +88,15 @@ public func index(_ arr: inout PtrByVal, _ arg: Int32, _ val: Int32) -> Int32 { // CHECK: bb0([[ARR:%.*]] : $*PtrByVal, [[INDEX:%.*]] : $Int32, [[NEWVALUE:%.*]] : $Int32): // CHECK: [[ARRACCESS:%.*]] = begin_access [modify] [static] [[ARR]] : $*PtrByVal // CHECK: [[ARRACCESS2:%.*]] = begin_access [modify] [static] [[ARRACCESS]] : $*PtrByVal -// CHECK: [[OP:%.*]] = function_ref [[PTRBYVAL:@(_ZN8PtrByValixEi|\?\?APtrByVal@@QEAAPEAHH@Z)]] : $@convention(c) (@inout PtrByVal, Int32) -> Optional> -// CHECK: [[PTR:%.*]] = apply [[OP]]([[ARRACCESS2]], [[INDEX]]) : $@convention(c) (@inout PtrByVal, Int32) -> Optional> +// CHECK: [[OP:%.*]] = function_ref [[PTRBYVAL:@(_ZN8PtrByValixEi|\?\?APtrByVal@@QEAAPEAHH@Z)]] : $@convention(cxx_method) (Int32, @inout PtrByVal) -> Optional> +// CHECK: [[PTR:%.*]] = apply [[OP]]([[INDEX]], [[ARRACCESS2]]) : $@convention(cxx_method) (Int32, @inout PtrByVal) -> Optional> // CHECK: } // end sil function '$s4main5indexys5Int32VSo8PtrByValVz_A2DtF' // CHECK: sil shared [transparent] @$sSo8PtrByValVySpys5Int32VGSgADcig : $@convention(method) (Int32, @inout PtrByVal) -> Optional> { // CHECK: bb0([[NEWVALUE:%.*]] : $Int32, [[INDEX:%.*]] : $*PtrByVal): // CHECK: [[SELFACCESS:%.*]] = begin_access [modify] [static] [[INDEX]] : $*PtrByVal -// CHECK: [[OP:%.*]] = function_ref [[PTRBYVAL]] : $@convention(c) (@inout PtrByVal, Int32) -> Optional> -// CHECK: [[PTR:%.*]] = apply [[OP]]([[SELFACCESS]], [[NEWVALUE]]) : $@convention(c) (@inout PtrByVal, Int32) -> Optional> +// CHECK: [[OP:%.*]] = function_ref [[PTRBYVAL]] : $@convention(cxx_method) (Int32, @inout PtrByVal) -> Optional> +// CHECK: [[PTR:%.*]] = apply [[OP]]([[NEWVALUE]], [[SELFACCESS]]) : $@convention(cxx_method) (Int32, @inout PtrByVal) -> Optional> // CHECK: end_access [[SELFACCESS]] : $*PtrByVal // CHECK: } // end sil function '$sSo8PtrByValVySpys5Int32VGSgADcig @@ -105,15 +105,15 @@ public func index(_ arr: inout RefToPtr, _ arg: Int32, _ val: Int32) -> Int32 { // CHECK: bb0([[ARR:%.*]] : $*RefToPtr, [[INDEX:%.*]] : $Int32, [[NEWVALUE:%.*]] : $Int32): // CHECK: [[ARRACCESS:%.*]] = begin_access [modify] [static] [[ARR]] : $*RefToPtr // CHECK: [[ARRACCESS2:%.*]] = begin_access [modify] [static] [[ARRACCESS]] : $*RefToPtr -// CHECK: [[OP:%.*]] = function_ref [[REFTOPTR:@(_ZN8RefToPtrixEi|\?\?ARefToPtr@@QEAAAEAPEAHH@Z)]] : $@convention(c) (@inout RefToPtr, Int32) -> UnsafeMutablePointer>> -// CHECK: [[PTR:%.*]] = apply [[OP]]([[ARRACCESS2]], [[INDEX]]) : $@convention(c) (@inout RefToPtr, Int32) -> UnsafeMutablePointer>> +// CHECK: [[OP:%.*]] = function_ref [[REFTOPTR:@(_ZN8RefToPtrixEi|\?\?ARefToPtr@@QEAAAEAPEAHH@Z)]] : $@convention(cxx_method) (Int32, @inout RefToPtr) -> UnsafeMutablePointer>> +// CHECK: [[PTR:%.*]] = apply [[OP]]([[INDEX]], [[ARRACCESS2]]) : $@convention(cxx_method) (Int32, @inout RefToPtr) -> UnsafeMutablePointer>> // CHECK: } // end sil function '$s4main5indexys5Int32VSo8RefToPtrVz_A2DtF' // CHECK: sil shared [transparent] @$sSo8RefToPtrVySpys5Int32VGSgADcig : $@convention(method) (Int32, @inout RefToPtr) -> Optional> { // CHECK: bb0([[NEWVALUE:%.*]] : $Int32, [[INDEX:%.*]] : $*RefToPtr): // CHECK: [[SELFACCESS:%.*]] = begin_access [modify] [static] [[INDEX]] : $*RefToPtr -// CHECK: [[OP:%.*]] = function_ref [[REFTOPTR]] : $@convention(c) (@inout RefToPtr, Int32) -> UnsafeMutablePointer>> -// CHECK: [[PTR:%.*]] = apply [[OP]]([[SELFACCESS]], [[NEWVALUE]]) : $@convention(c) (@inout RefToPtr, Int32) -> UnsafeMutablePointer>> +// CHECK: [[OP:%.*]] = function_ref [[REFTOPTR]] : $@convention(cxx_method) (Int32, @inout RefToPtr) -> UnsafeMutablePointer>> +// CHECK: [[PTR:%.*]] = apply [[OP]]([[NEWVALUE]], [[SELFACCESS]]) : $@convention(cxx_method) (Int32, @inout RefToPtr) -> UnsafeMutablePointer>> // CHECK: end_access [[SELFACCESS]] : $*RefToPtr // CHECK: } // end sil function '$sSo8RefToPtrVySpys5Int32VGSgADcig @@ -122,29 +122,29 @@ public func index(_ arr: inout PtrToPtr, _ arg: Int32, _ val: Int32) -> Int32 { // CHECK: bb0([[ARR:%.*]] : $*PtrToPtr, [[INDEX:%.*]] : $Int32, [[NEWVALUE:%.*]] : $Int32): // CHECK: [[ARRACCESS:%.*]] = begin_access [modify] [static] [[ARR]] : $*PtrToPtr // CHECK: [[ARRACCESS2:%.*]] = begin_access [modify] [static] [[ARRACCESS]] : $*PtrToPtr -// CHECK: [[OP:%.*]] = function_ref [[PTRTOPTR:@(_ZN8PtrToPtrixEi|\?\?APtrToPtr@@QEAAPEAPEAHH@Z)]] : $@convention(c) (@inout PtrToPtr, Int32) -> Optional>>> -// CHECK: [[PTR:%.*]] = apply [[OP]]([[ARRACCESS2]], [[INDEX]]) : $@convention(c) (@inout PtrToPtr, Int32) -> Optional>>> +// CHECK: [[OP:%.*]] = function_ref [[PTRTOPTR:@(_ZN8PtrToPtrixEi|\?\?APtrToPtr@@QEAAPEAPEAHH@Z)]] : $@convention(cxx_method) (Int32, @inout PtrToPtr) -> Optional>>> +// CHECK: [[PTR:%.*]] = apply [[OP]]([[INDEX]], [[ARRACCESS2]]) : $@convention(cxx_method) (Int32, @inout PtrToPtr) -> Optional>>> // CHECK: } // end sil function '$s4main5indexys5Int32VSo05PtrToD0Vz_A2DtF' // CHECK: sil shared [transparent] @$sSo05PtrToA0VySpySpys5Int32VGSgGSgADcig : $@convention(method) (Int32, @inout PtrToPtr) -> Optional>>> { // CHECK: bb0([[NEWVALUE:%.*]] : $Int32, [[INDEX:%.*]] : $*PtrToPtr): // CHECK: [[SELFACCESS:%.*]] = begin_access [modify] [static] [[INDEX]] : $*PtrToPtr -// CHECK: [[OP:%.*]] = function_ref [[PTRTOPTR]] : $@convention(c) (@inout PtrToPtr, Int32) -> Optional>>> -// CHECK: [[PTR:%.*]] = apply [[OP]]([[SELFACCESS]], [[NEWVALUE]]) : $@convention(c) (@inout PtrToPtr, Int32) -> Optional>>> +// CHECK: [[OP:%.*]] = function_ref [[PTRTOPTR]] : $@convention(cxx_method) (Int32, @inout PtrToPtr) -> Optional>>> +// CHECK: [[PTR:%.*]] = apply [[OP]]([[NEWVALUE]], [[SELFACCESS]]) : $@convention(cxx_method) (Int32, @inout PtrToPtr) -> Optional>>> // CHECK: end_access [[SELFACCESS]] : $*PtrToPtr // CHECK: } // end sil function '$sSo05PtrToA0VySpySpys5Int32VGSgGSgADcig public func index(_ arr: ConstOpPtrByVal, _ arg: Int32, _ val: Int32) -> Int32 { arr[arg]![0] } // CHECK: sil @$s4main5indexys5Int32VSo15ConstOpPtrByValV_A2DtF : $@convention(thin) (ConstOpPtrByVal, Int32, Int32) -> Int32 { // CHECK: bb0([[ARR:%.*]] : $ConstOpPtrByVal, [[INDEX:%.*]] : $Int32, [[NEWVALUE:%.*]] : $Int32): -// CHECK: [[OP:%.*]] = function_ref [[CONSTOPPTRBYVAL:@(_ZNK15ConstOpPtrByValixEi|\?\?AConstOpPtrByVal@@QEBAPEBHH@Z)]] : $@convention(c) (@in ConstOpPtrByVal, Int32) -> Optional> -// CHECK: [[PTR:%.*]] = apply [[OP]]([[ARRACCESS2:%.*]], [[INDEX]]) : $@convention(c) (@in ConstOpPtrByVal, Int32) -> Optional> +// CHECK: [[OP:%.*]] = function_ref [[CONSTOPPTRBYVAL:@(_ZNK15ConstOpPtrByValixEi|\?\?AConstOpPtrByVal@@QEBAPEBHH@Z)]] : $@convention(cxx_method) (Int32, @in_guaranteed ConstOpPtrByVal) -> Optional> +// CHECK: [[PTR:%.*]] = apply [[OP]]([[INDEX]], [[ARRACCESS2:%.*]]) : $@convention(cxx_method) (Int32, @in_guaranteed ConstOpPtrByVal) -> Optional> // CHECK: } // end sil function '$s4main5indexys5Int32VSo15ConstOpPtrByValV_A2DtF' // CHECK: sil shared [transparent] @$sSo15ConstOpPtrByValVySPys5Int32VGSgADcig : $@convention(method) (Int32, ConstOpPtrByVal) -> Optional> { // CHECK: bb0([[NEWVALUE:%.*]] : $Int32, [[INDEX:%.*]] : $ConstOpPtrByVal): -// CHECK: [[OP:%.*]] = function_ref [[CONSTOPPTRBYVAL]] : $@convention(c) (@in ConstOpPtrByVal, Int32) -> Optional> -// CHECK: [[PTR:%.*]] = apply [[OP]]([[SELFACCESS:%.*]], [[NEWVALUE]]) : $@convention(c) (@in ConstOpPtrByVal, Int32) -> Optional> +// CHECK: [[OP:%.*]] = function_ref [[CONSTOPPTRBYVAL]] : $@convention(cxx_method) (Int32, @in_guaranteed ConstOpPtrByVal) -> Optional> +// CHECK: [[PTR:%.*]] = apply [[OP]]([[NEWVALUE]], [[SELFACCESS:%.*]]) : $@convention(cxx_method) (Int32, @in_guaranteed ConstOpPtrByVal) -> Optional> // CHECK: } // end sil function '$sSo15ConstOpPtrByValVySPys5Int32VGSgADcig public func index(_ arr: inout ConstPtrByVal, _ arg: Int32, _ val: Int32) -> Int32 { arr[arg]![0] } @@ -152,24 +152,24 @@ public func index(_ arr: inout ConstPtrByVal, _ arg: Int32, _ val: Int32) -> Int // CHECK: bb0([[ARR:%.*]] : $*ConstPtrByVal, [[INDEX:%.*]] : $Int32, [[NEWVALUE:%.*]] : $Int32): // CHECK: [[ARRACCESS:%.*]] = begin_access [modify] [static] [[ARR]] : $*ConstPtrByVal // CHECK: [[ARRACCESS2:%.*]] = begin_access [modify] [static] [[ARRACCESS]] : $*ConstPtrByVal -// CHECK: [[OP:%.*]] = function_ref [[CONSTPTRBYVAL:@(_ZN13ConstPtrByValixEi|\?\?AConstPtrByVal@@QEAAPEBHH@Z)]] : $@convention(c) (@inout ConstPtrByVal, Int32) -> Optional> -// CHECK: [[PTR:%.*]] = apply [[OP]]([[ARRACCESS2]], [[INDEX]]) : $@convention(c) (@inout ConstPtrByVal, Int32) -> Optional> +// CHECK: [[OP:%.*]] = function_ref [[CONSTPTRBYVAL:@(_ZN13ConstPtrByValixEi|\?\?AConstPtrByVal@@QEAAPEBHH@Z)]] : $@convention(cxx_method) (Int32, @inout ConstPtrByVal) -> Optional> +// CHECK: [[PTR:%.*]] = apply [[OP]]([[INDEX]], [[ARRACCESS2]]) : $@convention(cxx_method) (Int32, @inout ConstPtrByVal) -> Optional> // CHECK: } // end sil function '$s4main5indexys5Int32VSo13ConstPtrByValVz_A2DtF' // CHECK: sil shared [transparent] @$sSo13ConstPtrByValVySPys5Int32VGSgADcig : $@convention(method) (Int32, @inout ConstPtrByVal) -> Optional> { // CHECK: bb0([[NEWVALUE:%.*]] : $Int32, [[INDEX:%.*]] : $*ConstPtrByVal): // CHECK: [[SELFACCESS:%.*]] = begin_access [modify] [static] [[INDEX]] : $*ConstPtrByVal -// CHECK: [[OP:%.*]] = function_ref [[CONSTPTRBYVAL]] : $@convention(c) (@inout ConstPtrByVal, Int32) -> Optional> -// CHECK: [[PTR:%.*]] = apply [[OP]]([[SELFACCESS]], [[NEWVALUE]]) : $@convention(c) (@inout ConstPtrByVal, Int32) -> Optional> +// CHECK: [[OP:%.*]] = function_ref [[CONSTPTRBYVAL]] : $@convention(cxx_method) (Int32, @inout ConstPtrByVal) -> Optional> +// CHECK: [[PTR:%.*]] = apply [[OP]]([[NEWVALUE]], [[SELFACCESS]]) : $@convention(cxx_method) (Int32, @inout ConstPtrByVal) -> Optional> // CHECK: end_access [[SELFACCESS]] : $*ConstPtrByVal // CHECK: } // end sil function '$sSo13ConstPtrByValVySPys5Int32VGSgADcig -// CHECK: sil [clang ReadOnlyIntArray.__operatorSubscriptConst] [[READCLASSNAME]] : $@convention(c) (@in ReadOnlyIntArray, Int32) -> UnsafePointer -// CHECK: sil [clang ReadWriteIntArray.__operatorSubscript] [[READWRITECLASSNAME]] : $@convention(c) (@inout ReadWriteIntArray, Int32) -> UnsafeMutablePointer -// CHECK: sil [clang NonTrivialIntArrayByVal.__operatorSubscriptConst] [[READWRITECLASSNAMEBYVAL]] : $@convention(c) (@in NonTrivialIntArrayByVal, Int32) -> Int32 +// CHECK: sil [clang ReadOnlyIntArray.__operatorSubscriptConst] [[READCLASSNAME]] : $@convention(cxx_method) (Int32, @in_guaranteed ReadOnlyIntArray) -> UnsafePointer +// CHECK: sil [clang ReadWriteIntArray.__operatorSubscript] [[READWRITECLASSNAME]] : $@convention(cxx_method) (Int32, @inout ReadWriteIntArray) -> UnsafeMutablePointer +// CHECK: sil [clang NonTrivialIntArrayByVal.__operatorSubscriptConst] [[READWRITECLASSNAMEBYVAL]] : $@convention(cxx_method) (Int32, @in_guaranteed NonTrivialIntArrayByVal) -> Int32 -// CHECK: sil [clang PtrByVal.__operatorSubscript] [[PTRBYVAL]] : $@convention(c) (@inout PtrByVal, Int32) -> Optional> -// CHECK: sil [clang RefToPtr.__operatorSubscript] [[REFTOPTR]] : $@convention(c) (@inout RefToPtr, Int32) -> UnsafeMutablePointer>> -// CHECK: sil [clang PtrToPtr.__operatorSubscript] [[PTRTOPTR]] : $@convention(c) (@inout PtrToPtr, Int32) -> Optional>>> -// CHECK: sil [clang ConstOpPtrByVal.__operatorSubscriptConst] [[CONSTOPPTRBYVAL]] : $@convention(c) (@in ConstOpPtrByVal, Int32) -> Optional> -// CHECK: sil [clang ConstPtrByVal.__operatorSubscriptConst] [[CONSTPTRBYVAL]] : $@convention(c) (@inout ConstPtrByVal, Int32) -> Optional> +// CHECK: sil [clang PtrByVal.__operatorSubscript] [[PTRBYVAL]] : $@convention(cxx_method) (Int32, @inout PtrByVal) -> Optional> +// CHECK: sil [clang RefToPtr.__operatorSubscript] [[REFTOPTR]] : $@convention(cxx_method) (Int32, @inout RefToPtr) -> UnsafeMutablePointer>> +// CHECK: sil [clang PtrToPtr.__operatorSubscript] [[PTRTOPTR]] : $@convention(cxx_method) (Int32, @inout PtrToPtr) -> Optional>>> +// CHECK: sil [clang ConstOpPtrByVal.__operatorSubscriptConst] [[CONSTOPPTRBYVAL]] : $@convention(cxx_method) (Int32, @in_guaranteed ConstOpPtrByVal) -> Optional> +// CHECK: sil [clang ConstPtrByVal.__operatorSubscriptConst] [[CONSTPTRBYVAL]] : $@convention(cxx_method) (Int32, @inout ConstPtrByVal) -> Optional> diff --git a/test/Interop/Cxx/templates/member-templates-silgen.swift b/test/Interop/Cxx/templates/member-templates-silgen.swift index 0ab3fab6f3f4b..2bbd98b130659 100644 --- a/test/Interop/Cxx/templates/member-templates-silgen.swift +++ b/test/Interop/Cxx/templates/member-templates-silgen.swift @@ -7,17 +7,17 @@ import MemberTemplates // CHECK-LABEL: sil hidden @$s4main9basicTestyyF : $@convention(thin) () -> () -// CHECK: [[ADD:%.*]] = function_ref @_ZN18HasMemberTemplates17addSameTypeParamsIiEET_S1_S1_ : $@convention(c) (Int32, Int32, @inout HasMemberTemplates) -> Int32 -// CHECK: apply [[ADD]]({{.*}}) : $@convention(c) (Int32, Int32, @inout HasMemberTemplates) -> Int32 +// CHECK: [[ADD:%.*]] = function_ref @_ZN18HasMemberTemplates17addSameTypeParamsIiEET_S1_S1_ : $@convention(cxx_method) (Int32, Int32, @inout HasMemberTemplates) -> Int32 +// CHECK: apply [[ADD]]({{.*}}) : $@convention(cxx_method) (Int32, Int32, @inout HasMemberTemplates) -> Int32 -// CHECK: [[ADD_TWO_TEMPLATES:%.*]] = function_ref @_ZN18HasMemberTemplates18addMixedTypeParamsIiiEET_S1_T0_ : $@convention(c) (Int32, Int32, @inout HasMemberTemplates) -> Int32 // user: %26 -// CHECK: apply [[ADD_TWO_TEMPLATES]]({{.*}}) : $@convention(c) (Int32, Int32, @inout HasMemberTemplates) -> Int32 +// CHECK: [[ADD_TWO_TEMPLATES:%.*]] = function_ref @_ZN18HasMemberTemplates18addMixedTypeParamsIiiEET_S1_T0_ : $@convention(cxx_method) (Int32, Int32, @inout HasMemberTemplates) -> Int32 // user: %26 +// CHECK: apply [[ADD_TWO_TEMPLATES]]({{.*}}) : $@convention(cxx_method) (Int32, Int32, @inout HasMemberTemplates) -> Int32 -// CHECK: [[ADD_ALL:%.*]] = function_ref @_ZN18HasMemberTemplates6addAllIiiEEiiT_T0_ : $@convention(c) (Int32, Int32, Int32, @inout HasMemberTemplates) -> Int32 // user: %39 -// CHECK: apply [[ADD_ALL]]({{.*}}) : $@convention(c) (Int32, Int32, Int32, @inout HasMemberTemplates) -> Int32 +// CHECK: [[ADD_ALL:%.*]] = function_ref @_ZN18HasMemberTemplates6addAllIiiEEiiT_T0_ : $@convention(cxx_method) (Int32, Int32, Int32, @inout HasMemberTemplates) -> Int32 // user: %39 +// CHECK: apply [[ADD_ALL]]({{.*}}) : $@convention(cxx_method) (Int32, Int32, Int32, @inout HasMemberTemplates) -> Int32 -// CHECK: [[DO_NOTHING:%.*]] = function_ref @_ZN18HasMemberTemplates17doNothingConstRefIiEEvRKT_ : $@convention(c) (UnsafePointer, @inout HasMemberTemplates) -> () // user: %48 -// CHECK: apply [[DO_NOTHING]]({{.*}}) : $@convention(c) (UnsafePointer, @inout HasMemberTemplates) -> () +// CHECK: [[DO_NOTHING:%.*]] = function_ref @_ZN18HasMemberTemplates17doNothingConstRefIiEEvRKT_ : $@convention(cxx_method) (UnsafePointer, @inout HasMemberTemplates) -> () // user: %48 +// CHECK: apply [[DO_NOTHING]]({{.*}}) : $@convention(cxx_method) (UnsafePointer, @inout HasMemberTemplates) -> () // CHECK-LABEL: end sil function '$s4main9basicTestyyF' func basicTest() { @@ -29,18 +29,18 @@ func basicTest() { obj.doNothingConstRef(&i) } -// CHECK-LABEL: sil hidden_external [clang HasMemberTemplates._ZN18HasMemberTemplates17addSameTypeParamsIiEET_S1_S1_] @_ZN18HasMemberTemplates17addSameTypeParamsIiEET_S1_S1_ : $@convention(c) (Int32, Int32, @inout HasMemberTemplates) -> Int32 +// CHECK-LABEL: sil hidden_external [clang HasMemberTemplates._ZN18HasMemberTemplates17addSameTypeParamsIiEET_S1_S1_] @_ZN18HasMemberTemplates17addSameTypeParamsIiEET_S1_S1_ : $@convention(cxx_method) (Int32, Int32, @inout HasMemberTemplates) -> Int32 -// CHECK-LABEL: sil hidden_external [clang HasMemberTemplates._ZN18HasMemberTemplates18addMixedTypeParamsIiiEET_S1_T0_] @_ZN18HasMemberTemplates18addMixedTypeParamsIiiEET_S1_T0_ : $@convention(c) (Int32, Int32, @inout HasMemberTemplates) -> Int32 +// CHECK-LABEL: sil hidden_external [clang HasMemberTemplates._ZN18HasMemberTemplates18addMixedTypeParamsIiiEET_S1_T0_] @_ZN18HasMemberTemplates18addMixedTypeParamsIiiEET_S1_T0_ : $@convention(cxx_method) (Int32, Int32, @inout HasMemberTemplates) -> Int32 -// CHECK-LABEL: sil hidden_external [clang HasMemberTemplates._ZN18HasMemberTemplates6addAllIiiEEiiT_T0_] @_ZN18HasMemberTemplates6addAllIiiEEiiT_T0_ : $@convention(c) (Int32, Int32, Int32, @inout HasMemberTemplates) -> Int32 +// CHECK-LABEL: sil hidden_external [clang HasMemberTemplates._ZN18HasMemberTemplates6addAllIiiEEiiT_T0_] @_ZN18HasMemberTemplates6addAllIiiEEiiT_T0_ : $@convention(cxx_method) (Int32, Int32, Int32, @inout HasMemberTemplates) -> Int32 -// CHECK-LABEL: sil hidden_external [clang HasMemberTemplates._ZN18HasMemberTemplates17doNothingConstRefIiEEvRKT_] @_ZN18HasMemberTemplates17doNothingConstRefIiEEvRKT_ : $@convention(c) (UnsafePointer, @inout HasMemberTemplates) -> () +// CHECK-LABEL: sil hidden_external [clang HasMemberTemplates._ZN18HasMemberTemplates17doNothingConstRefIiEEvRKT_] @_ZN18HasMemberTemplates17doNothingConstRefIiEEvRKT_ : $@convention(cxx_method) (UnsafePointer, @inout HasMemberTemplates) -> () // CHECK-LABEL: sil hidden @$s4main12testSetValueyyF : $@convention(thin) () -> () -// CHECK: [[SET_VALUE:%.*]] = function_ref @_ZN32TemplateClassWithMemberTemplatesIiE8setValueIlEEvT_ : $@convention(c) (Int, @inout __CxxTemplateInst32TemplateClassWithMemberTemplatesIiE) -> () -// CHECK: apply [[SET_VALUE]]({{.*}}) : $@convention(c) (Int, @inout __CxxTemplateInst32TemplateClassWithMemberTemplatesIiE) -> () +// CHECK: [[SET_VALUE:%.*]] = function_ref @_ZN32TemplateClassWithMemberTemplatesIiE8setValueIlEEvT_ : $@convention(cxx_method) (Int, @inout __CxxTemplateInst32TemplateClassWithMemberTemplatesIiE) -> () +// CHECK: apply [[SET_VALUE]]({{.*}}) : $@convention(cxx_method) (Int, @inout __CxxTemplateInst32TemplateClassWithMemberTemplatesIiE) -> () // CHECK-LABEL: end sil function '$s4main12testSetValueyyF' func testSetValue() { diff --git a/test/Interop/Cxx/templates/partially-pre-defined-class-template-silgen.swift b/test/Interop/Cxx/templates/partially-pre-defined-class-template-silgen.swift index f6054e9014cd2..fa932b9af60a2 100644 --- a/test/Interop/Cxx/templates/partially-pre-defined-class-template-silgen.swift +++ b/test/Interop/Cxx/templates/partially-pre-defined-class-template-silgen.swift @@ -13,9 +13,9 @@ public func getWrappedMagicInt() -> CInt { // CHECK: [[INT_WRAPPER:%.*]] = struct $IntWrapper ([[_:%.*]] : $Int32) // CHECK: [[_:%.*]] = struct $__CxxTemplateInst12MagicWrapperI10IntWrapperE ([[INT_WRAPPER]] : $IntWrapper) // CHECK: // function_ref {{_ZNK12MagicWrapperI10IntWrapperE15getValuePlusArgEi|\?getValuePlusArg@\?\$MagicWrapper@UIntWrapper@@@@QEBAHH@Z}} -// CHECK: [[_:%.*]] = function_ref @{{_ZNK12MagicWrapperI10IntWrapperE15getValuePlusArgEi|\?getValuePlusArg@\?\$MagicWrapper@UIntWrapper@@@@QEBAHH@Z}} : $@convention(c) (@in __CxxTemplateInst12MagicWrapperI10IntWrapperE, Int32) -> Int32 +// CHECK: [[_:%.*]] = function_ref @{{_ZNK12MagicWrapperI10IntWrapperE15getValuePlusArgEi|\?getValuePlusArg@\?\$MagicWrapper@UIntWrapper@@@@QEBAHH@Z}} : $@convention(cxx_method) (Int32, @in_guaranteed __CxxTemplateInst12MagicWrapperI10IntWrapperE) -> Int32 // CHECK: // {{_ZNK12MagicWrapperI10IntWrapperE15getValuePlusArgEi|\?getValuePlusArg@\?\$MagicWrapper@UIntWrapper@@@@QEBAHH@Z}} // CHECK: MagicWrapper::getValuePlusArg -// CHECK: sil [clang __CxxTemplateInst12MagicWrapperI10IntWrapperE.getValuePlusArg] @{{_ZNK12MagicWrapperI10IntWrapperE15getValuePlusArgEi|\?getValuePlusArg@\?\$MagicWrapper@UIntWrapper@@@@QEBAHH@Z}} : $@convention(c) (@in __CxxTemplateInst12MagicWrapperI10IntWrapperE, Int32) -> Int32 +// CHECK: sil [clang __CxxTemplateInst12MagicWrapperI10IntWrapperE.getValuePlusArg] @{{_ZNK12MagicWrapperI10IntWrapperE15getValuePlusArgEi|\?getValuePlusArg@\?\$MagicWrapper@UIntWrapper@@@@QEBAHH@Z}} : $@convention(cxx_method) (Int32, @in_guaranteed __CxxTemplateInst12MagicWrapperI10IntWrapperE) -> Int32