From fbb3382e2131dc7fd12c7551d73293f686292a27 Mon Sep 17 00:00:00 2001 From: Ellie Shin Date: Wed, 17 Apr 2024 22:16:18 -0700 Subject: [PATCH] During Package CMO, SIL cloning happens during which SILOptions::EnableSerializePackage info is lost. SILVerifier needs this info to determine whether resilience can be bypassed for decls serialized in a resiliently built module when Package CMO optimization enabled. This PR adds SerializePackageEnabled bit to Module format and uses that in SILVerifier. Resolves rdar://126157356 --- include/swift/AST/Decl.h | 7 +- include/swift/AST/Module.h | 10 + include/swift/Serialization/Validation.h | 5 + lib/AST/Module.cpp | 1 + lib/Frontend/Frontend.cpp | 2 + lib/SIL/Verifier/SILVerifier.cpp | 23 +- lib/Serialization/ModuleFile.h | 5 + lib/Serialization/ModuleFileSharedCore.cpp | 4 + lib/Serialization/ModuleFileSharedCore.h | 3 + lib/Serialization/ModuleFormat.h | 7 +- lib/Serialization/Serialization.cpp | 6 + lib/Serialization/SerializedModuleLoader.cpp | 2 + .../package-cmo-resilient-mode.swift | 299 ++++++++++++++---- 13 files changed, 312 insertions(+), 62 deletions(-) diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index 738d111cc266b..9be2d12e58bd1 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -697,7 +697,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated { HasAnyUnavailableDuringLoweringValues : 1 ); - SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1, + SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1, /// If the module is compiled as static library. StaticLibrary : 1, @@ -756,7 +756,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated { HasCxxInteroperability : 1, /// Whether this module has been built with -experimental-allow-non-resilient-access. - AllowNonResilientAccess : 1 + AllowNonResilientAccess : 1, + + /// Whether this module has been built with -experimental-package-cmo. + SerializePackageEnabled : 1 ); SWIFT_INLINE_BITFIELD(PrecedenceGroupDecl, Decl, 1+2, diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h index 15a009714c966..d1c211446daa3 100644 --- a/include/swift/AST/Module.h +++ b/include/swift/AST/Module.h @@ -721,6 +721,16 @@ class ModuleDecl Bits.ModuleDecl.AllowNonResilientAccess = flag; } + /// Returns true if -experimental-package-cmo was passed, which + /// enables serialization of package, public, and inlinable decls in a + /// package. This requires -experimental-allow-non-resilient-access. + bool serializePackageEnabled() const { + return Bits.ModuleDecl.SerializePackageEnabled; + } + void setSerializePackageEnabled(bool flag = true) { + Bits.ModuleDecl.SerializePackageEnabled = flag; + } + /// Returns true if this module is a non-Swift module that was imported into /// Swift. /// diff --git a/include/swift/Serialization/Validation.h b/include/swift/Serialization/Validation.h index d7b95270e6530..1b0855c20d56e 100644 --- a/include/swift/Serialization/Validation.h +++ b/include/swift/Serialization/Validation.h @@ -141,6 +141,7 @@ class ExtendedValidationInfo { unsigned IsConcurrencyChecked : 1; unsigned HasCxxInteroperability : 1; unsigned AllowNonResilientAccess: 1; + unsigned SerializePackageEnabled: 1; } Bits; public: ExtendedValidationInfo() : Bits() {} @@ -209,6 +210,10 @@ class ExtendedValidationInfo { void setAllowNonResilientAccess(bool val) { Bits.AllowNonResilientAccess = val; } + bool serializePackageEnabled() const { return Bits.SerializePackageEnabled; } + void setSerializePackageEnabled(bool val) { + Bits.SerializePackageEnabled = val; + } bool isAllowModuleWithCompilerErrorsEnabled() { return Bits.IsAllowModuleWithCompilerErrorsEnabled; } diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp index d7ecd98862c91..e5034964c6d34 100644 --- a/lib/AST/Module.cpp +++ b/lib/AST/Module.cpp @@ -723,6 +723,7 @@ ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx, Bits.ModuleDecl.ObjCNameLookupCachePopulated = 0; Bits.ModuleDecl.HasCxxInteroperability = 0; Bits.ModuleDecl.AllowNonResilientAccess = 0; + Bits.ModuleDecl.SerializePackageEnabled = 0; } void ModuleDecl::setIsSystemModule(bool flag) { diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 47f79296c605c..7491a472f22d8 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -1382,6 +1382,8 @@ ModuleDecl *CompilerInstance::getMainModule() const { MainModule->setHasCxxInteroperability(); if (Invocation.getLangOptions().AllowNonResilientAccess) MainModule->setAllowNonResilientAccess(); + if (Invocation.getSILOptions().EnableSerializePackage) + MainModule->setSerializePackageEnabled(); // Register the main module with the AST context. Context->addLoadedModule(MainModule); diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index 3ebf243594c5d..614af77184816 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -153,13 +153,28 @@ static bool isArchetypeValidInFunction(ArchetypeType *A, const SILFunction *F) { namespace { -/// When resilience is bypassed, direct access is legal, but the decls are still -/// resilient. +/// When resilience is bypassed for debugging or package serialization is enabled, +/// direct access is legal, but the decls are still resilient. template bool checkResilience(DeclType *D, ModuleDecl *M, ResilienceExpansion expansion) { - return !D->getModuleContext()->getBypassResilience() && - D->isResilient(M, expansion); + auto refDeclModule = D->getModuleContext(); + // Explicitly bypassed for debugging with `bypass-resilience-checks` + if (refDeclModule->getBypassResilience()) + return false; + + // If package serialization is enabled with `experimental-package-cmo`, + // decls can be serialized in a resiliently built module. In such case, + // a direct access should be allowed. + auto packageSerialized = expansion == ResilienceExpansion::Minimal && + refDeclModule->isResilient() && + refDeclModule->allowNonResilientAccess() && + refDeclModule->serializePackageEnabled() && + refDeclModule->inSamePackage(M); + if (packageSerialized) + return false; + + return D->isResilient(M, expansion); } bool checkTypeABIAccessible(SILFunction const &F, SILType ty) { diff --git a/lib/Serialization/ModuleFile.h b/lib/Serialization/ModuleFile.h index 4b53b80536dc1..bbc53f087daf7 100644 --- a/lib/Serialization/ModuleFile.h +++ b/lib/Serialization/ModuleFile.h @@ -659,6 +659,11 @@ class ModuleFile return Core->Bits.AllowNonResilientAccess; } + /// Whether this module was built with -experimental-package-cmo. + bool serializePackageEnabled() const { + return Core->Bits.SerializePackageEnabled; + } + /// Whether this module is compiled with implicit dynamic. bool isImplicitDynamicEnabled() const { return Core->Bits.IsImplicitDynamicEnabled; diff --git a/lib/Serialization/ModuleFileSharedCore.cpp b/lib/Serialization/ModuleFileSharedCore.cpp index fe6404ebd3ef0..26ff2ecc84ab1 100644 --- a/lib/Serialization/ModuleFileSharedCore.cpp +++ b/lib/Serialization/ModuleFileSharedCore.cpp @@ -200,6 +200,9 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor, case options_block::ALLOW_NON_RESILIENT_ACCESS: extendedInfo.setAllowNonResilientAccess(true); break; + case options_block::SERIALIZE_PACKAGE_ENABLED: + extendedInfo.setSerializePackageEnabled(true); + break; default: // Unknown options record, possibly for use by a future version of the // module format. @@ -1448,6 +1451,7 @@ ModuleFileSharedCore::ModuleFileSharedCore( Bits.IsConcurrencyChecked = extInfo.isConcurrencyChecked(); Bits.HasCxxInteroperability = extInfo.hasCxxInteroperability(); Bits.AllowNonResilientAccess = extInfo.allowNonResilientAccess(); + Bits.SerializePackageEnabled = extInfo.serializePackageEnabled(); MiscVersion = info.miscVersion; ModuleABIName = extInfo.getModuleABIName(); ModulePackageName = extInfo.getModulePackageName(); diff --git a/lib/Serialization/ModuleFileSharedCore.h b/lib/Serialization/ModuleFileSharedCore.h index 24c3eaa5ceb86..dba0017ac0db9 100644 --- a/lib/Serialization/ModuleFileSharedCore.h +++ b/lib/Serialization/ModuleFileSharedCore.h @@ -391,6 +391,9 @@ class ModuleFileSharedCore { /// Whether this module is built with -experimental-allow-non-resilient-access. unsigned AllowNonResilientAccess : 1; + /// Whether this module is built with -experimental-package-cmo. + unsigned SerializePackageEnabled : 1; + // Explicitly pad out to the next word boundary. unsigned : 3; } Bits = {}; diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index d819e6a612878..b19b5fc5464c6 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 869; // @implementation +const uint16_t SWIFTMODULE_VERSION_MINOR = 870; // SerializePackageEnabled /// A standard hash seed used for all string hashes in a serialized module. /// @@ -941,6 +941,7 @@ namespace options_block { PLUGIN_SEARCH_OPTION, HAS_CXX_INTEROPERABILITY_ENABLED, ALLOW_NON_RESILIENT_ACCESS, + SERIALIZE_PACKAGE_ENABLED, }; using SDKPathLayout = BCRecordLayout< @@ -1027,6 +1028,10 @@ namespace options_block { using AllowNonResilientAccess = BCRecordLayout< ALLOW_NON_RESILIENT_ACCESS >; + + using SerializePackageEnabled = BCRecordLayout< + SERIALIZE_PACKAGE_ENABLED + >; } /// The record types within the input block. diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 9fe0323aee6a5..5e709375781e3 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -855,6 +855,7 @@ void Serializer::writeBlockInfoBlock() { BLOCK_RECORD(options_block, MODULE_EXPORT_AS_NAME); BLOCK_RECORD(options_block, PLUGIN_SEARCH_OPTION); BLOCK_RECORD(options_block, ALLOW_NON_RESILIENT_ACCESS); + BLOCK_RECORD(options_block, SERIALIZE_PACKAGE_ENABLED); BLOCK(INPUT_BLOCK); BLOCK_RECORD(input_block, IMPORTED_MODULE); @@ -1092,6 +1093,11 @@ void Serializer::writeHeader() { AllowNonResAcess.emit(ScratchRecord); } + if (M->serializePackageEnabled()) { + options_block::SerializePackageEnabled SerializePkgEnabled(Out); + SerializePkgEnabled.emit(ScratchRecord); + } + if (allowCompilerErrors()) { options_block::IsAllowModuleWithCompilerErrorsEnabledLayout AllowErrors(Out); diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index 2c607f409821a..a3d54ce4f445f 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -923,6 +923,8 @@ LoadedFile *SerializedModuleLoaderBase::loadAST( M.setIsBuiltFromInterface(); if (loadedModuleFile->allowNonResilientAccess()) M.setAllowNonResilientAccess(); + if (loadedModuleFile->serializePackageEnabled()) + M.setSerializePackageEnabled(); if (!loadedModuleFile->getModuleABIName().empty()) M.setABIName(Ctx.getIdentifier(loadedModuleFile->getModuleABIName())); if (loadedModuleFile->isConcurrencyChecked()) diff --git a/test/SILOptimizer/package-cmo-resilient-mode.swift b/test/SILOptimizer/package-cmo-resilient-mode.swift index f7ab3228ac22e..2b7a6837c04be 100644 --- a/test/SILOptimizer/package-cmo-resilient-mode.swift +++ b/test/SILOptimizer/package-cmo-resilient-mode.swift @@ -7,11 +7,11 @@ // RUN: -Xfrontend -experimental-package-cmo -Xfrontend -experimental-allow-non-resilient-access \ // RUN: -O -wmo -// RUN: %target-sil-opt %t/Lib.swiftmodule -sil-verify-all -o %t/Lib-sil-opt.sil -// RUN: %FileCheck %s --check-prefix=CHECK-NONRES < %t/Lib-sil-opt.sil +// RUN: %target-sil-opt %t/Lib.swiftmodule -sil-verify-all -o %t/Lib-non-res.sil +// RUN: %FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-NONRES < %t/Lib-non-res.sil -// RUN: %target-build-swift -module-name=Main -package-name Pkg -I%t -emit-sil %t/main.swift -o %t/Main.sil -// RUN: %FileCheck %s --check-prefix=CHECK-ACCESS-NONRES < %t/Main.sil +// RUN: %target-build-swift -module-name=Main -package-name Pkg -I%t -emit-sil %t/main.swift -o %t/Main-non-res.sil +// RUN: %FileCheck %s --check-prefixes=CHECK-MAIN-COMMON,CHECK-MAIN-NONRES < %t/Main-non-res.sil // RUN: rm -rf %t/Lib.swiftmodule @@ -21,11 +21,14 @@ // RUN: -Xfrontend -experimental-package-cmo -Xfrontend -experimental-allow-non-resilient-access \ // RUN: -O -wmo -enable-library-evolution -// RUN: %target-sil-opt %t/Lib.swiftmodule -sil-verify-all -o %t/Lib-sil-opt.sil -// RUN: %FileCheck %s --check-prefix=CHECK-RES < %t/Lib-sil-opt.sil +// RUN: %target-sil-opt %t/Lib.swiftmodule -sil-verify-all -o %t/Lib-res.sil +// RUN: %FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-RES < %t/Lib-res.sil -// RUN: %target-build-swift -module-name=Main -package-name Pkg -I%t -emit-sil %t/main.swift -o %t/Main.sil -// RUN: %FileCheck %s --check-prefix=CHECK-ACCESS-RES < %t/Main.sil +// RUN: %target-build-swift -module-name=Main -package-name Pkg -I%t -emit-sil %t/main.swift -o %t/Main-res.sil +// RUN: %FileCheck %s --check-prefixes=CHECK-MAIN-COMMON,CHECK-MAIN-RES < %t/Main-res.sil + +// RUN: llvm-bcanalyzer --dump %t/Lib.swiftmodule | %FileCheck %s --check-prefix=CHECK-BC +// CHECK-BC: SERIALIZE_PACKAGE_ENABLED // REQUIRES: swift_in_compiler @@ -33,55 +36,94 @@ import Lib -// CHECK-ACCESS-NONRES-NOT: s3Lib9PubStructV6fooVarSivg -// CHECK-ACCESS-NONRES-NOT: s3Lib9PubStructV6fooVarSivs -// CHECK-ACCESS-NONRES-NOT: s3Lib9PkgStructV6fooVarSivg -// CHECK-ACCESS-NONRES-NOT: s3Lib9PubStructV6fooVarSivs - -// CHECK-ACCESS-RES: function_ref @$s3Lib9PubStructVyACSicfC : $@convention(method) (Int, @thin PubStruct.Type) -> @out PubStruct -// CHECK-ACCESS-NONRES: function_ref @$s3Lib9PubStructVyACSicfC : $@convention(method) (Int, @thin PubStruct.Type) -> PubStruct - -// CHECK-ACCESS-RES: function_ref @$s3Lib9PubStructV6fooVarSivg : $@convention(method) (@in_guaranteed PubStruct) -> Int -// CHECK-ACCESS-NONRES: [[PUB_GET:%.*]] = begin_access [read] [dynamic] {{.*}} : $*PubStruct -// CHECK-ACCESS-NONRES: struct_element_addr [[PUB_GET]] : $*PubStruct, #PubStruct.fooVar - -// CHECK-ACCESS-RES: function_ref @$s3Lib9PubStructV6fooVarSivs : $@convention(method) (Int, @inout PubStruct) -> () -// CHECK-ACCESS-NONRES: [[PUB_MODIFY:%.*]] = begin_access [modify] [dynamic] {{.*}} : $*PubStruct -// CHECK-ACCESS-NONRES: struct_element_addr [[PUB_MODIFY]] : $*PubStruct, #PubStruct.fooVar - -// CHECK-ACCESS-RES: function_ref @$s3Lib6runPubyyAA0C6StructVF : $@convention(thin) (@in_guaranteed PubStruct) -> () -// CHECK-ACCESS-NONRES: function_ref @$s3Lib6runPubyyAA0C6StructVF : $@convention(thin) (PubStruct) -> () - -// CHECK-ACCESS-RES: function_ref @$s3Lib9PkgStructV6fooVarSivg : $@convention(method) (@in_guaranteed PkgStruct) -> Int -// CHECK-ACCESS-NONRES: [[PKG_GET:%.*]] = begin_access [read] [dynamic] {{.*}} : $*PkgStruct -// CHECK-ACCESS-NONRES: struct_element_addr [[PKG_GET]] : $*PkgStruct, #PkgStruct.fooVar - -// CHECK-ACCESS-RES: function_ref @$s3Lib9PkgStructV6fooVarSivs : $@convention(method) (Int, @inout PkgStruct) -> () -// CHECK-ACCESS-NONRES: [[PKG_MODIFY:%.*]] = begin_access [modify] [dynamic] {{.*}} : $*PkgStruct -// CHECK-ACCESS-NONRES: struct_element_addr [[PKG_MODIFY]] : $*PkgStruct, #PkgStruct.fooVar - -// CHECK-ACCESS-RES: function_ref @$s3Lib6runPkgyyAA0C6StructVF : $@convention(thin) (@in_guaranteed PkgStruct) -> () -// CHECK-ACCESS-NONRES: function_ref @$s3Lib6runPkgyyAA0C6StructVF : $@convention(thin) (PkgStruct) -> () - -var p = PubStruct(1) -let prev = p.fooVar -p.fooVar = 3 -runPub(p) -print(prev) +// CHECK-MAIN-COMMON-NOT: s3Lib8PubKlassC4dataSivg +// CHECK-MAIN-COMMON-NOT: s3Lib8PubKlassC4dataSivs +// CHECK-MAIN-COMMON-NOT: s3Lib8PkgKlassC4dataSivg +// CHECK-MAIN-COMMON-NOT: s3Lib8PkgKlassC4dataSivs +// CHECK-MAIN-NONRES-NOT: s3Lib9PubStructV6fooVarSivg +// CHECK-MAIN-NONRES-NOT: s3Lib9PubStructV6fooVarSivs +// CHECK-MAIN-NONRES-NOT: s3Lib9PkgStructV6fooVarSivg +// CHECK-MAIN-NONRES-NOT: s3Lib9PubStructV6fooVarSivs + +// CHECK-MAIN-RES: function_ref @$s3Lib9PubStructVyACSicfC : $@convention(method) (Int, @thin PubStruct.Type) -> @out PubStruct +// CHECK-MAIN-NONRES: function_ref @$s3Lib9PubStructVyACSicfC : $@convention(method) (Int, @thin PubStruct.Type) -> PubStruct + +// CHECK-MAIN-RES: function_ref @$s3Lib9PubStructV6fooVarSivg : $@convention(method) (@in_guaranteed PubStruct) -> Int +// CHECK-MAIN-NONRES: [[PUB_GET:%.*]] = begin_access [read] [dynamic] {{.*}} : $*PubStruct +// CHECK-MAIN-NONRES: struct_element_addr [[PUB_GET]] : $*PubStruct, #PubStruct.fooVar + +// CHECK-MAIN-RES: function_ref @$s3Lib9PubStructV6fooVarSivs : $@convention(method) (Int, @inout PubStruct) -> () +// CHECK-MAIN-NONRES: [[PUB_MODIFY:%.*]] = begin_access [modify] [dynamic] {{.*}} : $*PubStruct +// CHECK-MAIN-NONRES: struct_element_addr [[PUB_MODIFY]] : $*PubStruct, #PubStruct.fooVar + +// CHECK-MAIN-RES: function_ref @$s3Lib6runPubyyAA0C6StructVF : $@convention(thin) (@in_guaranteed PubStruct) -> () +// CHECK-MAIN-NONRES: function_ref @$s3Lib6runPubyyAA0C6StructVF : $@convention(thin) (PubStruct) -> () + +// CHECK-MAIN-COMMON: function_ref @$s3Lib11FrPubStructVyACSicfC : $@convention(method) (Int, @thin FrPubStruct.Type) -> FrPubStruct +// CHECK-MAIN-COMMON: begin_access [read] [dynamic] {{.*}} : $*FrPubStruct +// CHECK-MAIN-COMMON-NEXT: struct_element_addr {{.*}} : $*FrPubStruct, #FrPubStruct.fooVar +// CHECK-MAIN-COMMON-NEXT: copy_addr +// CHECK-MAIN-COMMON: begin_access [modify] [dynamic] {{.*}} : $*FrPubStruct +// CHECK-MAIN-COMMON-NEXT: struct_element_addr {{.*}} : $*FrPubStruct, #FrPubStruct.fooVar +// CHECK-MAIN-COMMON-NEXT: store +// CHECK-MAIN-COMMON: begin_access [read] [dynamic] {{.*}} : $*FrPubStruct +// CHECK-MAIN-COMMON-NEXT: load +// CHECK-MAIN-COMMON: function_ref @$s3Lib8runFrPubyyAA0cD6StructVF : $@convention(thin) (FrPubStruct) -> () + +// CHECK-MAIN-RES: function_ref @$s3Lib9PkgStructV6fooVarSivg : $@convention(method) (@in_guaranteed PkgStruct) -> Int +// CHECK-MAIN-NONRES: [[PKG_GET:%.*]] = begin_access [read] [dynamic] {{.*}} : $*PkgStruct +// CHECK-MAIN-NONRES: struct_element_addr [[PKG_GET]] : $*PkgStruct, #PkgStruct.fooVar + +// CHECK-MAIN-RES: function_ref @$s3Lib9PkgStructV6fooVarSivs : $@convention(method) (Int, @inout PkgStruct) -> () +// CHECK-MAIN-NONRES: [[PKG_MODIFY:%.*]] = begin_access [modify] [dynamic] {{.*}} : $*PkgStruct +// CHECK-MAIN-NONRES: struct_element_addr [[PKG_MODIFY]] : $*PkgStruct, #PkgStruct.fooVar + +// CHECK-MAIN-RES: function_ref @$s3Lib6runPkgyyAA0C6StructVF : $@convention(thin) (@in_guaranteed PkgStruct) -> () +// CHECK-MAIN-NONRES: function_ref @$s3Lib6runPkgyyAA0C6StructVF : $@convention(thin) (PkgStruct) -> () + +// CHECK-MAIN-COMMON: function_ref @$s3Lib8PubKlassCyACSicfC : $@convention(method) (Int, @thick PubKlass.Type) -> @owned PubKlass +// CHECK-MAIN-COMMON: begin_access [read] [dynamic] {{.*}} : $*PubKlass +// CHECK-MAIN-COMMON: class_method {{.*}} : $PubKlass, #PubKlass.data!getter : (PubKlass) -> () -> Int, $@convention(method) (@guaranteed PubKlass) -> Int +// CHECK-MAIN-COMMON: class_method {{.*}} : $PubKlass, #PubKlass.data!setter : (PubKlass) -> (Int) -> (), $@convention(method) (Int, @guaranteed PubKlass) -> () +// CHECK-MAIN-COMMON: function_ref @$s3Lib11runPubKlassyyAA0cD0CF : $@convention(thin) (@guaranteed PubKlass) -> () + +// CHECK-MAIN-COMMON: function_ref @$s3Lib8PkgKlassCyACSicfC : $@convention(method) (Int, @thick PkgKlass.Type) -> @owned PkgKlass +// CHECK-MAIN-COMMON: begin_access [read] [dynamic] {{.*}} : $*PkgKlass +// CHECK-MAIN-COMMON: class_method {{.*}} : $PkgKlass, #PkgKlass.data!getter : (PkgKlass) -> () -> Int, $@convention(method) (@guaranteed PkgKlass) -> Int +// CHECK-MAIN-COMMON: class_method {{.*}} : $PkgKlass, #PkgKlass.data!setter : (PkgKlass) -> (Int) -> (), $@convention(method) (Int, @guaranteed PkgKlass) -> () +// CHECK-MAIN-COMMON: function_ref @$s3Lib11runPkgKlassyyAA0cD0CF : $@convention(thin) (@guaranteed PkgKlass) -> () + +var pub = PubStruct(1) +let prevPub = pub.fooVar +pub.fooVar = 3 +runPub(pub) +print(prevPub) // PubStruct.init(_:) -// CHECK-ACCESS-RES: sil @$s3Lib9PubStructVyACSicfC : $@convention(method) (Int, @thin PubStruct.Type) -> @out PubStruct -// CHECK-ACCESS-NONRES: sil @$s3Lib9PubStructVyACSicfC : $@convention(method) (Int, @thin PubStruct.Type) -> PubStruct +// CHECK-MAIN-RES: sil @$s3Lib9PubStructVyACSicfC : $@convention(method) (Int, @thin PubStruct.Type) -> @out PubStruct +// CHECK-MAIN-NONRES: sil @$s3Lib9PubStructVyACSicfC : $@convention(method) (Int, @thin PubStruct.Type) -> PubStruct // PubStruct.fooVar.getter -// CHECK-ACCESS-RES: sil @$s3Lib9PubStructV6fooVarSivg : $@convention(method) (@in_guaranteed PubStruct) -> Int +// CHECK-MAIN-RES: sil @$s3Lib9PubStructV6fooVarSivg : $@convention(method) (@in_guaranteed PubStruct) -> Int // PubStruct.fooVar.setter -// CHECK-ACCESS-RES: sil @$s3Lib9PubStructV6fooVarSivs : $@convention(method) (Int, @inout PubStruct) -> () +// CHECK-MAIN-RES: sil @$s3Lib9PubStructV6fooVarSivs : $@convention(method) (Int, @inout PubStruct) -> () // runPub(_:) -// CHECK-ACCESS-RES: sil @$s3Lib6runPubyyAA0C6StructVF : $@convention(thin) (@in_guaranteed PubStruct) -> () -// CHECK-ACCESS-NONRES: sil @$s3Lib6runPubyyAA0C6StructVF : $@convention(thin) (PubStruct) -> () +// CHECK-MAIN-RES: sil @$s3Lib6runPubyyAA0C6StructVF : $@convention(thin) (@in_guaranteed PubStruct) -> () +// CHECK-MAIN-NONRES: sil @$s3Lib6runPubyyAA0C6StructVF : $@convention(thin) (PubStruct) -> () + +var frpub = FrPubStruct(1) +let prevFrPub = frpub.fooVar +frpub.fooVar = 3 +runFrPub(frpub) +print(prevFrPub) + +// FrPubStruct.init(_:) +// CHECK-MAIN-COMMON: sil @$s3Lib11FrPubStructVyACSicfC : $@convention(method) (Int, @thin FrPubStruct.Type) -> FrPubStruct + +// runFrPub(_:) +// CHECK-MAIN-COMMON: sil @$s3Lib8runFrPubyyAA0cD6StructVF : $@convention(thin) (FrPubStruct) -> () var pkg = PkgStruct(1) let prevPkg = pkg.fooVar @@ -90,18 +132,42 @@ runPkg(pkg) print(prevPkg) // PkgStruct.init(_:) -// CHECK-ACCESS-RES: sil package_external @$s3Lib9PkgStructVyACSicfC : $@convention(method) (Int, @thin PkgStruct.Type) -> @out PkgStruct -// CHECK-ACCESS-NONRES: sil package_external @$s3Lib9PkgStructVyACSicfC : $@convention(method) (Int, @thin PkgStruct.Type) -> PkgStruct +// CHECK-MAIN-RES: sil package_external @$s3Lib9PkgStructVyACSicfC : $@convention(method) (Int, @thin PkgStruct.Type) -> @out PkgStruct +// CHECK-MAIN-NONRES: sil package_external @$s3Lib9PkgStructVyACSicfC : $@convention(method) (Int, @thin PkgStruct.Type) -> PkgStruct // PkgStruct.fooVar.getter -// CHECK-ACCESS-RES: sil package_external @$s3Lib9PkgStructV6fooVarSivg : $@convention(method) (@in_guaranteed PkgStruct) -> Int +// CHECK-MAIN-RES: sil package_external @$s3Lib9PkgStructV6fooVarSivg : $@convention(method) (@in_guaranteed PkgStruct) -> Int // PkgStruct.fooVar.setter -// CHECK-ACCESS-RES: sil package_external @$s3Lib9PkgStructV6fooVarSivs : $@convention(method) (Int, @inout PkgStruct) -> () +// CHECK-MAIN-RES: sil package_external @$s3Lib9PkgStructV6fooVarSivs : $@convention(method) (Int, @inout PkgStruct) -> () // runPkg(_:) -// CHECK-ACCESS-RES: sil package_external @$s3Lib6runPkgyyAA0C6StructVF : $@convention(thin) (@in_guaranteed PkgStruct) -> () -// CHECK-ACCESS-NONRES: sil package_external @$s3Lib6runPkgyyAA0C6StructVF : $@convention(thin) (PkgStruct) -> () +// CHECK-MAIN-RES: sil package_external @$s3Lib6runPkgyyAA0C6StructVF : $@convention(thin) (@in_guaranteed PkgStruct) -> () +// CHECK-MAIN-NONRES: sil package_external @$s3Lib6runPkgyyAA0C6StructVF : $@convention(thin) (PkgStruct) -> () + +var pubKlass = PubKlass(2) +let prevPubData = pubKlass.data +pubKlass.data = 5 +runPubKlass(pubKlass) +print(prevPubData) + +// PubKlass.__allocating_init(_:) +// CHECK-MAIN-COMMON: sil @$s3Lib8PubKlassCyACSicfC : $@convention(method) (Int, @thick PubKlass.Type) -> @owned PubKlass + +// runPubKlass(_:) +// CHECK-MAIN-COMMON: sil @$s3Lib11runPubKlassyyAA0cD0CF : $@convention(thin) (@guaranteed PubKlass) -> () + +var pkgKlass = PkgKlass(2) +let prevPkgData = pkgKlass.data +pkgKlass.data = 5 +runPkgKlass(pkgKlass) +print(prevPkgData) + +// PkgKlass.__allocating_init(_:) +// CHECK-MAIN-COMMON: sil package_external @$s3Lib8PkgKlassCyACSicfC : $@convention(method) (Int, @thick PkgKlass.Type) -> @owned PkgKlass + +// runPkgKlass(_:) +// CHECK-MAIN-COMMON: sil package_external @$s3Lib11runPkgKlassyyAA0cD0CF : $@convention(thin) (@guaranteed PkgKlass) -> () //--- Lib.swift @@ -135,6 +201,26 @@ public func runPub(_ arg: PubStruct) { print(arg) } +@frozen +public struct FrPubStruct { + // CHECK-COMMON-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib11FrPubStructV6fooVarSivM : $@yield_once @convention(method) (@inout FrPubStruct) -> @yields @inout Int { + // CHECK-COMMON-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib11FrPubStructV6fooVarSivg : $@convention(method) (FrPubStruct) -> Int { + // CHECK-COMMON-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib11FrPubStructV6fooVarSivs : $@convention(method) (Int, @inout FrPubStruct) -> () { + public var fooVar: Int + public init(_ arg: Int) { + // CHECK-COMMON-DAG: sil [serialized] [canonical] @$s3Lib11FrPubStructVyACSicfC : $@convention(method) (Int, @thin FrPubStruct.Type) -> FrPubStruct { + fooVar = arg + } + public func f() { + // CHECK-NONRES-DAG: sil [serialized] [canonical] @$s3Lib11FrPubStructV1fyyF : $@convention(method) (FrPubStruct) -> () { + print(fooVar) + } +} +public func runFrPub(_ arg: FrPubStruct) { + // CHECK-NONRES-DAG: sil [serialized] [canonical] @$s3Lib8runFrPubyyAA0cD6StructVF : $@convention(thin) (FrPubStruct) -> () { + print(arg) +} + package struct PkgStruct { // fooVar.getter // CHECK-NONRES-DAG: sil package [transparent] [serialized] [canonical] [ossa] @$s3Lib9PkgStructV6fooVarSivg : $@convention(method) (PkgStruct) -> Int { @@ -158,3 +244,106 @@ package func runPkg(_ arg: PkgStruct) { // CHECK-NONRES-DAG: sil package [serialized] [canonical] @$s3Lib6runPkgyyAA0C6StructVF : $@convention(thin) (PkgStruct) -> () { print(arg) } + +public protocol PubProto { + var data: Int { get set } + func pubfunc(_ arg: Int) -> Int +} + +public class PubKlass: PubProto { + // CHECK-COMMON-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivgTW : $@convention(witness_method: PubProto) (@in_guaranteed PubKlass) -> Int { + // CHECK-COMMON-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivMTW : $@yield_once @convention(witness_method: PubProto) @substituted <τ_0_0> (@inout τ_0_0) -> @yields @inout Int for { + // CHECK-COMMON-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivsTW : $@convention(witness_method: PubProto) (Int, @inout PubKlass) -> () { + // CHECK-RES-DAG: sil [serialized] [canonical] @$s3Lib8PubKlassC4dataSivg : $@convention(method) (@guaranteed PubKlass) -> Int + // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib8PubKlassC4dataSivg : $@convention(method) (@guaranteed PubKlass) -> Int { + // CHECK-RES-DAG: sil [serialized] [canonical] @$s3Lib8PubKlassC4dataSivs : $@convention(method) (Int, @guaranteed PubKlass) -> () { + // CHECK-NONRES-DAG: sil [transparent] [serialized] [canonical] [ossa] @$s3Lib8PubKlassC4dataSivs : $@convention(method) (Int, @guaranteed PubKlass) -> () { + public var data: Int + public init(_ arg: Int = 1) { + // default argument 0 of PubKlass.init(_:) + // CHECK-COMMON-DAG: sil non_abi [serialized] [canonical] @$s3Lib8PubKlassCyACSicfcfA_ : $@convention(thin) () -> Int { + // CHECK-COMMON-DAG: sil [serialized] [canonical] @$s3Lib8PubKlassCyACSicfc : $@convention(method) (Int, @owned PubKlass) -> @owned PubKlass { + // CHECK-COMMON-DAG: sil [serialized] [exact_self_class] [canonical] @$s3Lib8PubKlassCyACSicfC : $@convention(method) (Int, @thick PubKlass.Type) -> @owned PubKlass { + // CHECK-COMMON-DAG: sil [serialized] [canonical] @$s3Lib8PubKlassCfD : $@convention(method) (@owned PubKlass) -> () { + // CHECK-COMMON-DAG: sil [serialized] [canonical] @$s3Lib8PubKlassCfd : $@convention(method) (@guaranteed PubKlass) -> @owned Builtin.NativeObject { + self.data = arg + } + public func pubfunc(_ arg: Int) -> Int { + // CHECK-COMMON-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PubKlassCAA0B5ProtoA2aDP7pubfuncyS2iFTW : $@convention(witness_method: PubProto) (Int, @in_guaranteed PubKlass) -> Int { + // CHECK-COMMON-DAG: sil [serialized] [canonical] @$s3Lib8PubKlassC7pubfuncyS2iF : $@convention(method) (Int, @guaranteed PubKlass) -> Int { + return data + arg + } +} + +public func runPubKlass(_ arg: PubKlass) { + // CHECK-NONRES-DAG: sil [serialized] [canonical] @$s3Lib11runPubKlassyyAA0cD0CF : $@convention(thin) (@guaranteed PubKlass) -> () { + print(arg) +} + +package protocol PkgProto { + var data: Int { get set } + func pkgfunc(_ arg: Int) -> Int +} + +package class PkgKlass: PkgProto { + // CHECK-COMMON-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivgTW : $@convention(witness_method: PkgProto) (@in_guaranteed PkgKlass) -> Int { + // CHECK-COMMON-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivsTW : $@convention(witness_method: PkgProto) (Int, @inout PkgKlass) -> () { + // CHECK-COMMON-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivMTW : $@yield_once @convention(witness_method: PkgProto) @substituted <τ_0_0> (@inout τ_0_0) -> @yields @inout Int for { + // CHECK-RES-DAG: sil package [serialized] [canonical] @$s3Lib8PkgKlassC4dataSivM : $@yield_once @convention(method) (@guaranteed PkgKlass) -> @yields @inout Int { + // CHECK-NONRES-DAG: sil package [transparent] [serialized] [canonical] [ossa] @$s3Lib8PkgKlassC4dataSivM : $@yield_once @convention(method) (@guaranteed PkgKlass) -> @yields @inout Int { + // CHECK-RES-DAG: sil package [serialized] [canonical] @$s3Lib8PkgKlassC4dataSivg : $@convention(method) (@guaranteed PkgKlass) -> Int { + // CHECK-NONRES-DAG: sil package [transparent] [serialized] [canonical] [ossa] @$s3Lib8PkgKlassC4dataSivg : $@convention(method) (@guaranteed PkgKlass) -> Int { + // CHECK-RES-DAG: sil package [serialized] [canonical] @$s3Lib8PkgKlassC4dataSivs : $@convention(method) (Int, @guaranteed PkgKlass) -> () { + // CHECK-NONRES-DAG: sil package [transparent] [serialized] [canonical] [ossa] @$s3Lib8PkgKlassC4dataSivs : $@convention(method) (Int, @guaranteed PkgKlass) -> () { + package var data: Int + + package init(_ arg: Int = 1) { + // FIXME: package -> package_non_abi for default argument 0 of PkgKlass.init(_:) + // CHECK-COMMON-DAG: sil package [serialized] [canonical] @$s3Lib8PkgKlassCyACSicfcfA_ : $@convention(thin) () -> Int { + // CHECK-COMMON-DAG: sil package [serialized] [canonical] @$s3Lib8PkgKlassCyACSicfc : $@convention(method) (Int, @owned PkgKlass) -> @owned PkgKlass { + // CHECK-COMMON-DAG: sil package [serialized] [exact_self_class] [canonical] @$s3Lib8PkgKlassCyACSicfC : $@convention(method) (Int, @thick PkgKlass.Type) -> @owned PkgKlass { + // CHECK-COMMON-DAG: sil package [serialized] [canonical] @$s3Lib8PkgKlassCfd : $@convention(method) (@guaranteed PkgKlass) -> @owned Builtin.NativeObject { + // CHECK-COMMON-DAG: sil package [serialized] [canonical] @$s3Lib8PkgKlassCfD : $@convention(method) (@owned PkgKlass) -> () + self.data = arg + } + + package func pkgfunc(_ arg: Int) -> Int { + // CHECK-COMMON-DAG: sil shared [transparent] [serialized] [thunk] [canonical] [ossa] @$s3Lib8PkgKlassCAA0B5ProtoA2aDP7pkgfuncyS2iFTW : $@convention(witness_method: PkgProto) (Int, @in_guaranteed PkgKlass) -> Int { + // CHECK-COMMON-DAG: sil package [serialized] [canonical] @$s3Lib8PkgKlassC7pkgfuncyS2iF : $@convention(method) (Int, @guaranteed PkgKlass) -> Int { + return data + arg + } +} + +package func runPkgKlass(_ arg: PkgKlass) { + // CHECK-NONRES-DAG: sil package [serialized] [canonical] @$s3Lib11runPkgKlassyyAA0cD0CF : $@convention(thin) (@guaranteed PkgKlass) -> () { + print(arg) +} + + +// CHECK-COMMON-LABEL: sil_vtable [serialized] PubKlass { +// CHECK-COMMON-NEXT: #PubKlass.data!getter: (PubKlass) -> () -> Int : @$s3Lib8PubKlassC4dataSivg +// CHECK-COMMON-NEXT: #PubKlass.data!setter: (PubKlass) -> (Int) -> () : @$s3Lib8PubKlassC4dataSivs +// CHECK-COMMON-NEXT: #PubKlass.data!modify: (PubKlass) -> () -> () : @$s3Lib8PubKlassC4dataSivM +// CHECK-COMMON-NEXT: #PubKlass.init!allocator: (PubKlass.Type) -> (Int) -> PubKlass : @$s3Lib8PubKlassCyACSicfC +// CHECK-COMMON-NEXT: #PubKlass.pubfunc: (PubKlass) -> (Int) -> Int : @$s3Lib8PubKlassC7pubfuncyS2iF +// CHECK-COMMON-NEXT: #PubKlass.deinit!deallocator: @$s3Lib8PubKlassCfD + +// CHECK-COMMON-LABEL: sil_vtable [serialized] PkgKlass { +// CHECK-COMMON-NEXT: #PkgKlass.data!getter: (PkgKlass) -> () -> Int : @$s3Lib8PkgKlassC4dataSivg +// CHECK-COMMON-NEXT: #PkgKlass.data!setter: (PkgKlass) -> (Int) -> () : @$s3Lib8PkgKlassC4dataSivs +// CHECK-COMMON-NEXT: #PkgKlass.data!modify: (PkgKlass) -> () -> () : @$s3Lib8PkgKlassC4dataSivM +// CHECK-COMMON-NEXT: #PkgKlass.init!allocator: (PkgKlass.Type) -> (Int) -> PkgKlass : @$s3Lib8PkgKlassCyACSicfC +// CHECK-COMMON-NEXT: #PkgKlass.pkgfunc: (PkgKlass) -> (Int) -> Int : @$s3Lib8PkgKlassC7pkgfuncyS2iF +// CHECK-COMMON-NEXT: #PkgKlass.deinit!deallocator: @$s3Lib8PkgKlassCfD + +// CHECK-COMMON-LABEL: sil_witness_table [serialized] PubKlass: PubProto module Lib { +// CHECK-COMMON-NEXT: method #PubProto.data!getter: (Self) -> () -> Int : @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivgTW +// CHECK-COMMON-NEXT: method #PubProto.data!setter: (inout Self) -> (Int) -> () : @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivsTW +// CHECK-COMMON-NEXT: method #PubProto.data!modify: (inout Self) -> () -> () : @$s3Lib8PubKlassCAA0B5ProtoA2aDP4dataSivMTW +// CHECK-COMMON-NEXT: method #PubProto.pubfunc: (Self) -> (Int) -> Int : @$s3Lib8PubKlassCAA0B5ProtoA2aDP7pubfuncyS2iFTW + +// CHECK-COMMON-LABEL: sil_witness_table package [serialized] PkgKlass: PkgProto module Lib { +// CHECK-COMMON-NEXT: method #PkgProto.data!getter: (Self) -> () -> Int : @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivgTW +// CHECK-COMMON-NEXT: method #PkgProto.data!setter: (inout Self) -> (Int) -> () : @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivsTW +// CHECK-COMMON-NEXT: method #PkgProto.data!modify: (inout Self) -> () -> () : @$s3Lib8PkgKlassCAA0B5ProtoA2aDP4dataSivMTW +// CHECK-COMMON-NEXT: method #PkgProto.pkgfunc: (Self) -> (Int) -> Int : @$s3Lib8PkgKlassCAA0B5ProtoA2aDP7pkgfuncyS2iFTW