From 036361d1e4ffec54cc83cbc97382c97e628cb597 Mon Sep 17 00:00:00 2001 From: zoecarver Date: Tue, 4 Jan 2022 16:15:04 -0800 Subject: [PATCH] [cxx-interop] Add SIL function representation cxx_method; Support extending C++ types. There are three major changes here: 1. The addition of "SILFunctionTypeRepresentation::CXXMethod". 2. C++ methods are imported with their members *last*. Then the arguments are switched when emitting the IR for an application of the function. 3. Clang decls are now marked as foreign witnesses. These are all steps towards being able to have C++ protocol conformance. --- docs/ABI/Mangling.rst | 4 +- include/swift/AST/ExtInfo.h | 13 +++ include/swift/SIL/ApplySite.h | 1 + lib/AST/ASTDumper.cpp | 2 + lib/AST/ASTMangler.cpp | 1 + lib/AST/ASTPrinter.cpp | 6 + lib/AST/ClangTypeConverter.cpp | 1 + lib/AST/ExtInfo.cpp | 1 + lib/ClangImporter/ImportDecl.cpp | 12 +- lib/ClangImporter/ImportType.cpp | 6 +- lib/IRGen/Callee.h | 3 + lib/IRGen/GenCall.cpp | 50 +++++++-- lib/IRGen/GenFunc.cpp | 2 + lib/IRGen/GenPointerAuth.cpp | 2 + lib/IRGen/GenProto.cpp | 1 + lib/IRGen/IRGenSIL.cpp | 3 + lib/IRGen/MetadataRequest.cpp | 2 + lib/SIL/IR/Bridging.cpp | 4 +- lib/SIL/IR/SILFunctionType.cpp | 24 +++- lib/SIL/Utils/InstructionUtils.cpp | 1 + lib/SILGen/SILGenExpr.cpp | 2 + lib/SILGen/SILGenPoly.cpp | 11 ++ lib/SILGen/SILGenType.cpp | 13 ++- .../FunctionSignatureOpts.cpp | 1 + .../Mandatory/MandatoryInlining.cpp | 1 + lib/Serialization/ModuleFormat.h | 3 +- lib/Serialization/Serialization.cpp | 1 + .../Cxx/class/Inputs/protocol-conformance.h | 21 +++- .../class/protocol-conformance-irgen.swift | 19 ++++ .../class/protocol-conformance-silgen.swift | 15 ++- .../Cxx/class/protocol-conformance.swift | 104 ++++++++++++++++++ .../foreign-reference/move-only-silgen.swift | 6 +- .../Cxx/foreign-reference/pod-silgen.swift | 6 +- .../foreign-reference/singleton-silgen.swift | 6 +- .../Cxx/operators/member-inline-silgen.swift | 92 ++++++++-------- .../templates/member-templates-silgen.swift | 28 ++--- ...ly-pre-defined-class-template-silgen.swift | 4 +- 37 files changed, 370 insertions(+), 102 deletions(-) create mode 100644 test/Interop/Cxx/class/protocol-conformance-irgen.swift create mode 100644 test/Interop/Cxx/class/protocol-conformance.swift 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