diff --git a/include/swift/SIL/SILLinkage.h b/include/swift/SIL/SILLinkage.h index 56b5365cde307..47008dd55fb15 100644 --- a/include/swift/SIL/SILLinkage.h +++ b/include/swift/SIL/SILLinkage.h @@ -35,6 +35,17 @@ enum class SILLinkage : unsigned char { /// other object definitions with this name in the program. Public, + /// This is a special linkage used for symbols which are treated + /// as public for the purposes of SIL serialization and optimization, + /// but do not have public entry points in the generated binary. + /// + /// There is no external variant of this linkage, because from other + /// translation units in the same module, this behaves identically + /// to the HiddenExternal linkage. + /// + /// When deserialized, such declarations receive Shared linkage. + PublicNonABI, + /// This object definition is visible only to the current Swift /// module (and thus should not be visible across linkage-unit /// boundaries). There are no other object definitions with this @@ -83,7 +94,7 @@ enum class SILLinkage : unsigned char { enum { /// The number of bits required to store a SILLinkage value. - NumSILLinkageBits = 3 + NumSILLinkageBits = 4 }; /// Related to linkage: flag if a function or global variable is serialized, @@ -125,15 +136,28 @@ inline SILLinkage stripExternalFromLinkage(SILLinkage linkage) { /// Add the 'external' attribute to \p linkage. inline SILLinkage addExternalToLinkage(SILLinkage linkage) { - if (linkage == SILLinkage::Public) + switch (linkage) { + case SILLinkage::Public: return SILLinkage::PublicExternal; - if (linkage == SILLinkage::Hidden) + case SILLinkage::PublicNonABI: + // An external reference to a public non-ABI function is only valid + // if the function was emitted in another translation unit of the + // same Swift module, so we treat it as hidden here. return SILLinkage::HiddenExternal; - if (linkage == SILLinkage::Shared) + case SILLinkage::Shared: return SILLinkage::SharedExternal; - if (linkage == SILLinkage::Private) + case SILLinkage::Hidden: + return SILLinkage::HiddenExternal; + case SILLinkage::Private: return SILLinkage::PrivateExternal; - return linkage; + case SILLinkage::PublicExternal: + case SILLinkage::SharedExternal: + case SILLinkage::PrivateExternal: + case SILLinkage::HiddenExternal: + return linkage; + } + + llvm_unreachable("Unhandled SILLinkage in switch."); } /// Return whether the linkage indicates that an object has a @@ -147,23 +171,24 @@ inline bool isAvailableExternally(SILLinkage linkage) { /// If \p is true then we are in whole-module compilation. inline bool isPossiblyUsedExternally(SILLinkage linkage, bool wholeModule) { if (wholeModule) { - return linkage <= SILLinkage::Public; + return linkage <= SILLinkage::PublicNonABI; } return linkage <= SILLinkage::Hidden; } inline bool hasPublicVisibility(SILLinkage linkage) { switch (linkage) { - case SILLinkage::Public: - case SILLinkage::PublicExternal: - return true; - case SILLinkage::Hidden: - case SILLinkage::Shared: - case SILLinkage::SharedExternal: - case SILLinkage::Private: - case SILLinkage::PrivateExternal: - case SILLinkage::HiddenExternal: - return false; + case SILLinkage::Public: + case SILLinkage::PublicExternal: + case SILLinkage::PublicNonABI: + return true; + case SILLinkage::Hidden: + case SILLinkage::Shared: + case SILLinkage::SharedExternal: + case SILLinkage::Private: + case SILLinkage::PrivateExternal: + case SILLinkage::HiddenExternal: + return false; } llvm_unreachable("Unhandled SILLinkage in switch."); @@ -176,6 +201,7 @@ inline bool hasSharedVisibility(SILLinkage linkage) { return true; case SILLinkage::Public: case SILLinkage::PublicExternal: + case SILLinkage::PublicNonABI: case SILLinkage::Hidden: case SILLinkage::HiddenExternal: case SILLinkage::Private: @@ -193,6 +219,7 @@ inline bool hasPrivateVisibility(SILLinkage linkage) { return true; case SILLinkage::Public: case SILLinkage::PublicExternal: + case SILLinkage::PublicNonABI: case SILLinkage::Hidden: case SILLinkage::HiddenExternal: case SILLinkage::Shared: diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h index ca5060cfb21a8..73500501aff83 100644 --- a/include/swift/Serialization/ModuleFormat.h +++ b/include/swift/Serialization/ModuleFormat.h @@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0; /// in source control, you should also update the comment to briefly /// 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. -const uint16_t VERSION_MINOR = 392; // Last change: accessor decls +const uint16_t VERSION_MINOR = 393; // SILLinkage::PublicNonABI using DeclIDField = BCFixed<31>; diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp index cf17b9f7597e1..91a0d565f0c35 100644 --- a/lib/IRGen/GenDecl.cpp +++ b/lib/IRGen/GenDecl.cpp @@ -1478,6 +1478,7 @@ getIRLinkage(const UniversalLinkageInfo &info, SILLinkage linkage, : RESULT(External, Hidden, Default); case SILLinkage::Hidden: + case SILLinkage::PublicNonABI: return RESULT(External, Hidden, Default); case SILLinkage::Private: { diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp index 8507aa1fc06a8..6cc8e043e958c 100644 --- a/lib/ParseSIL/ParseSIL.cpp +++ b/lib/ParseSIL/ParseSIL.cpp @@ -747,6 +747,7 @@ static bool parseSILLinkage(Optional &Result, Parser &P) { // Then use a string switch to try and parse the identifier. Result = llvm::StringSwitch>(P.Tok.getText()) + .Case("non_abi", SILLinkage::PublicNonABI) .Case("hidden", SILLinkage::Hidden) .Case("shared", SILLinkage::Shared) .Case("public_external", SILLinkage::PublicExternal) diff --git a/lib/SIL/SILDeclRef.cpp b/lib/SIL/SILDeclRef.cpp index a0da3fa9840ad..6e068ca53ec02 100644 --- a/lib/SIL/SILDeclRef.cpp +++ b/lib/SIL/SILDeclRef.cpp @@ -271,6 +271,13 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const { if (isClangImported()) return SILLinkage::Shared; + // Default argument generators of Public functions have PublicNonABI linkage + // if the function was type-checked in Swift 4 mode. + if (kind == SILDeclRef::Kind::DefaultArgGenerator) { + if (isSerialized()) + return maybeAddExternal(SILLinkage::PublicNonABI); + } + bool neverPublic = false; // ivar initializers and destroyers are completely contained within the class @@ -281,15 +288,13 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const { // Stored property initializers get the linkage of their containing type. if (isStoredPropertyInitializer()) { - // If the property is public, the initializer needs to be public, because - // it might be referenced from an inlineable initializer. + // If the type is public, the property initializer is referenced from + // inlinable initializers, and has PublicNonABI linkage. // // Note that we don't serialize the presence of an initializer, so there's // no way to reference one from another module except for this case. - // - // This is silly, and we need a proper resilience story here. - if (d->getEffectiveAccess() == AccessLevel::Public) - return maybeAddExternal(SILLinkage::Public); + if (isSerialized()) + return maybeAddExternal(SILLinkage::PublicNonABI); // Otherwise, use the visibility of the type itself, because even if the // property is private, we might reference the initializer from another diff --git a/lib/SIL/SILModule.cpp b/lib/SIL/SILModule.cpp index dbdf982384b61..ebecbde9ee06f 100644 --- a/lib/SIL/SILModule.cpp +++ b/lib/SIL/SILModule.cpp @@ -60,6 +60,12 @@ class SILModule::SerializationCallback : public SerializedSILLoader::Callback { case SILLinkage::Public: decl->setLinkage(SILLinkage::PublicExternal); return; + case SILLinkage::PublicNonABI: + // PublicNonABI functions receive SharedExternal linkage, so that + // they have "link once" semantics when deserialized by multiple + // translation units in the same Swift module. + decl->setLinkage(SILLinkage::SharedExternal); + return; case SILLinkage::Hidden: decl->setLinkage(SILLinkage::HiddenExternal); return; @@ -67,8 +73,8 @@ class SILModule::SerializationCallback : public SerializedSILLoader::Callback { decl->setLinkage(SILLinkage::SharedExternal); return; case SILLinkage::Private: - decl->setLinkage(SILLinkage::PrivateExternal); - return; + decl->setLinkage(SILLinkage::PrivateExternal); + return; case SILLinkage::PublicExternal: case SILLinkage::HiddenExternal: case SILLinkage::SharedExternal: diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp index 3fcdc100979d3..d7c8e59e119eb 100644 --- a/lib/SIL/SILPrinter.cpp +++ b/lib/SIL/SILPrinter.cpp @@ -2192,6 +2192,7 @@ void SILFunction::dump(const char *FileName) const { static StringRef getLinkageString(SILLinkage linkage) { switch (linkage) { case SILLinkage::Public: return "public "; + case SILLinkage::PublicNonABI: return "non_abi "; case SILLinkage::Hidden: return "hidden "; case SILLinkage::Shared: return "shared "; case SILLinkage::Private: return "private "; diff --git a/lib/SILOptimizer/IPO/GlobalOpt.cpp b/lib/SILOptimizer/IPO/GlobalOpt.cpp index b969d199abc89..6266fb612ab0d 100644 --- a/lib/SILOptimizer/IPO/GlobalOpt.cpp +++ b/lib/SILOptimizer/IPO/GlobalOpt.cpp @@ -225,16 +225,46 @@ static std::string mangleGetter(VarDecl *varDecl) { return Mangler.mangleGlobalGetterEntity(varDecl); } +static SILFunction *getGlobalGetterFunction(SILModule &M, + SILLocation loc, + VarDecl *varDecl) { + auto getterName = mangleGetter(varDecl); + + // Check if a getter was generated already. + if (auto *F = M.lookUpFunction(getterName)) + return F; + + auto Linkage = (varDecl->getEffectiveAccess() >= AccessLevel::Public + ? SILLinkage::PublicNonABI + : SILLinkage::Private); + auto Serialized = (varDecl->getEffectiveAccess() >= AccessLevel::Public + ? IsSerialized + : IsNotSerialized); + + auto refType = M.Types.getLoweredType(varDecl->getInterfaceType()); + + // Function takes no arguments and returns refType + SILResultInfo Results[] = { SILResultInfo(refType.getSwiftRValueType(), + ResultConvention::Owned) }; + SILFunctionType::ExtInfo EInfo; + EInfo = EInfo.withRepresentation(SILFunctionType::Representation::Thin); + auto LoweredType = + SILFunctionType::get(nullptr, EInfo, + SILCoroutineKind::None, + ParameterConvention::Direct_Unowned, + /*params*/ {}, /*yields*/ {}, Results, None, + M.getASTContext()); + + return M.getOrCreateFunction( + loc, getterName, Linkage, LoweredType, + IsBare, IsNotTransparent, Serialized); +} + /// Generate getter from the initialization code whose /// result is stored by a given store instruction. static SILFunction *genGetterFromInit(StoreInst *Store, SILGlobalVariable *SILG) { auto *varDecl = SILG->getDecl(); - auto getterName = mangleGetter(varDecl); - - // Check if a getter was generated already. - if (auto *F = Store->getModule().lookUpFunction(getterName)) - return F; // Find the code that performs the initialization first. // Recursively walk the SIL value being assigned to the SILG. @@ -253,25 +283,15 @@ static SILFunction *genGetterFromInit(StoreInst *Store, Insns.push_back(ReverseInsns.pop_back_val()); } - // Generate a getter from the global init function without side-effects. - auto refType = varDecl->getInterfaceType()->getCanonicalType(); - // Function takes no arguments and returns refType - SILResultInfo Results[] = { SILResultInfo(refType, ResultConvention::Owned) }; - SILFunctionType::ExtInfo EInfo; - EInfo = EInfo.withRepresentation(SILFunctionType::Representation::Thin); - auto LoweredType = SILFunctionType::get(nullptr, EInfo, - SILCoroutineKind::None, ParameterConvention::Direct_Owned, - /*params*/ {}, /*yields*/ {}, Results, None, - Store->getModule().getASTContext()); - auto *GetterF = Store->getModule().getOrCreateFunction( - Store->getLoc(), - getterName, SILLinkage::Private, LoweredType, - IsBare_t::IsBare, IsTransparent_t::IsNotTransparent, - IsSerialized_t::IsSerialized); + auto *GetterF = getGlobalGetterFunction(Store->getModule(), + Store->getLoc(), + varDecl); + GetterF->setDebugScope(Store->getFunction()->getDebugScope()); if (!Store->getFunction()->hasQualifiedOwnership()) GetterF->setUnqualifiedOwnership(); auto *EntryBB = GetterF->createBasicBlock(); + // Copy instructions into GetterF InstructionsCloner Cloner(*GetterF, Insns, EntryBB); Cloner.clone(); @@ -503,26 +523,9 @@ void SILGlobalOpt::placeInitializers(SILFunction *InitF, static SILFunction *genGetterFromInit(SILFunction *InitF, VarDecl *varDecl) { // Generate a getter from the global init function without side-effects. - auto getterName = mangleGetter(varDecl); - - // Check if a getter was generated already. - if (auto *F = InitF->getModule().lookUpFunction(getterName)) - return F; - - auto refType = varDecl->getInterfaceType()->getCanonicalType(); - // Function takes no arguments and returns refType - SILResultInfo Results[] = { SILResultInfo(refType, ResultConvention::Owned) }; - SILFunctionType::ExtInfo EInfo; - EInfo = EInfo.withRepresentation(SILFunctionType::Representation::Thin); - auto LoweredType = SILFunctionType::get(nullptr, EInfo, - SILCoroutineKind::None, ParameterConvention::Direct_Owned, - /*params*/ {}, /*yields*/ {}, Results, None, - InitF->getASTContext()); - auto *GetterF = InitF->getModule().getOrCreateFunction( - InitF->getLocation(), - getterName, SILLinkage::Private, LoweredType, - IsBare_t::IsBare, IsTransparent_t::IsNotTransparent, - IsSerialized_t::IsSerialized); + auto *GetterF = getGlobalGetterFunction(InitF->getModule(), + InitF->getLocation(), + varDecl); if (!InitF->hasQualifiedOwnership()) GetterF->setUnqualifiedOwnership(); diff --git a/lib/SILOptimizer/UtilityPasses/InstCount.cpp b/lib/SILOptimizer/UtilityPasses/InstCount.cpp index 9501a3f8beebb..82ccc062d6303 100644 --- a/lib/SILOptimizer/UtilityPasses/InstCount.cpp +++ b/lib/SILOptimizer/UtilityPasses/InstCount.cpp @@ -44,6 +44,7 @@ STATISTIC(TotalExternalFuncDecls, "Number of external funcs declarations"); // Linkage statistics STATISTIC(TotalPublicFuncs, "Number of public funcs"); +STATISTIC(TotalPublicNonABIFuncs, "Number of public non-ABI funcs"); STATISTIC(TotalHiddenFuncs, "Number of hidden funcs"); STATISTIC(TotalPrivateFuncs, "Number of private funcs"); STATISTIC(TotalSharedFuncs, "Number of shared funcs"); @@ -117,6 +118,9 @@ class InstCount : public SILFunctionTransform { case SILLinkage::Public: ++TotalPublicFuncs; break; + case SILLinkage::PublicNonABI: + ++TotalPublicNonABIFuncs; + break; case SILLinkage::Hidden: ++TotalHiddenFuncs; break; diff --git a/lib/Serialization/DeserializeSIL.cpp b/lib/Serialization/DeserializeSIL.cpp index 5160ef054ac15..32b1684dab28e 100644 --- a/lib/Serialization/DeserializeSIL.cpp +++ b/lib/Serialization/DeserializeSIL.cpp @@ -66,6 +66,7 @@ static Optional fromStableSILLinkage(unsigned value) { switch (value) { case SIL_LINKAGE_PUBLIC: return SILLinkage::Public; + case SIL_LINKAGE_PUBLIC_NON_ABI: return SILLinkage::PublicNonABI; case SIL_LINKAGE_HIDDEN: return SILLinkage::Hidden; case SIL_LINKAGE_SHARED: return SILLinkage::Shared; case SIL_LINKAGE_PRIVATE: return SILLinkage::Private; @@ -469,7 +470,14 @@ SILFunction *SILDeserializer::readSILFunction(DeclID FID, fn->setSerialized(IsSerialized_t(isSerialized)); // Don't override the transparency or linkage of a function with - // an existing declaration. + // an existing declaration, except if we deserialized a + // PublicNonABI function, which has HiddenExternal when + // referenced as a declaration, and SharedExternal when it has + // a deserialized body. + if (fn->getLinkage() == SILLinkage::HiddenExternal && + linkage == SILLinkage::PublicNonABI) { + fn->setLinkage(SILLinkage::SharedExternal); + } // Otherwise, create a new function. } else { diff --git a/lib/Serialization/SILFormat.h b/lib/Serialization/SILFormat.h index 55267a5f47e82..856473ff66db8 100644 --- a/lib/Serialization/SILFormat.h +++ b/lib/Serialization/SILFormat.h @@ -37,6 +37,7 @@ enum SILStringEncoding : uint8_t { enum SILLinkageEncoding : uint8_t { SIL_LINKAGE_PUBLIC, + SIL_LINKAGE_PUBLIC_NON_ABI, SIL_LINKAGE_HIDDEN, SIL_LINKAGE_SHARED, SIL_LINKAGE_PRIVATE, @@ -45,7 +46,7 @@ enum SILLinkageEncoding : uint8_t { SIL_LINKAGE_SHARED_EXTERNAL, SIL_LINKAGE_PRIVATE_EXTERNAL, }; -using SILLinkageField = BCFixed<3>; +using SILLinkageField = BCFixed<4>; enum SILVTableEntryKindEncoding : uint8_t { SIL_VTABLE_ENTRY_NORMAL, diff --git a/lib/Serialization/SerializeSIL.cpp b/lib/Serialization/SerializeSIL.cpp index 3c1b1569dca50..039178c0f3d24 100644 --- a/lib/Serialization/SerializeSIL.cpp +++ b/lib/Serialization/SerializeSIL.cpp @@ -64,6 +64,7 @@ toStableConstStringEncoding(ConstStringLiteralInst::Encoding encoding) { static unsigned toStableSILLinkage(SILLinkage linkage) { switch (linkage) { case SILLinkage::Public: return SIL_LINKAGE_PUBLIC; + case SILLinkage::PublicNonABI: return SIL_LINKAGE_PUBLIC_NON_ABI; case SILLinkage::Hidden: return SIL_LINKAGE_HIDDEN; case SILLinkage::Shared: return SIL_LINKAGE_SHARED; case SILLinkage::Private: return SIL_LINKAGE_PRIVATE; diff --git a/lib/TBDGen/TBDGen.cpp b/lib/TBDGen/TBDGen.cpp index 18737eaf31be0..8ca4d02b0785f 100644 --- a/lib/TBDGen/TBDGen.cpp +++ b/lib/TBDGen/TBDGen.cpp @@ -36,31 +36,10 @@ using namespace swift::irgen; using namespace swift::tbdgen; using StringSet = llvm::StringSet<>; -static bool isPrivateDecl(ValueDecl *VD) { - return getDeclLinkage(VD) != FormalLinkage::PublicUnique; -} - static bool isGlobalOrStaticVar(VarDecl *VD) { return VD->isStatic() || VD->getDeclContext()->isModuleScopeContext(); } -void TBDGenVisitor::visitPatternBindingDecl(PatternBindingDecl *PBD) { - for (auto &entry : PBD->getPatternList()) { - auto *var = entry.getAnchoringVarDecl(); - if (isPrivateDecl(var)) - return; - - // Non-global variables might have an explicit initializer symbol. - if (entry.getInit() && !isGlobalOrStaticVar(var)) { - auto declRef = - SILDeclRef(var, SILDeclRef::Kind::StoredPropertyInitializer); - // Stored property initializers for public properties are currently - // public. - addSymbol(declRef); - } - } -} - void TBDGenVisitor::addSymbol(SILDeclRef declRef) { auto linkage = effectiveLinkageForClassMember( declRef.getLinkage(ForDefinition), @@ -125,8 +104,11 @@ void TBDGenVisitor::addConformances(DeclContext *DC) { void TBDGenVisitor::visitAbstractFunctionDecl(AbstractFunctionDecl *AFD) { addSymbol(SILDeclRef(AFD)); - // Default arguments (of public functions) are public symbols, as the default - // values are computed at the call site. + if (!SwiftModule->getASTContext().isSwiftVersion3()) + return; + + // In Swift 3, default arguments (of public functions) are public symbols, + // as the default values are computed at the call site. auto index = 0; auto paramLists = AFD->getParameterLists(); // Skip the first arguments, which contains Self (etc.), can't be defaulted, @@ -177,7 +159,7 @@ void TBDGenVisitor::visitNominalTypeDecl(NominalTypeDecl *NTD) { } void TBDGenVisitor::visitClassDecl(ClassDecl *CD) { - if (isPrivateDecl(CD)) + if (getDeclLinkage(CD) != FormalLinkage::PublicUnique) return; auto &ctxt = CD->getASTContext(); diff --git a/lib/TBDGen/TBDGenVisitor.h b/lib/TBDGen/TBDGenVisitor.h index 17c6d48de8b12..ddd11b07efc2a 100644 --- a/lib/TBDGen/TBDGenVisitor.h +++ b/lib/TBDGen/TBDGenVisitor.h @@ -84,14 +84,8 @@ class TBDGenVisitor : public ASTVisitor { addSymbol("main"); } - void visitPatternBindingDecl(PatternBindingDecl *PBD); - void visitAbstractFunctionDecl(AbstractFunctionDecl *AFD); - void visitTypeAliasDecl(TypeAliasDecl *TAD) { - // any information here is encoded elsewhere - } - void visitNominalTypeDecl(NominalTypeDecl *NTD); void visitClassDecl(ClassDecl *CD); diff --git a/test/IRGen/sil_linkage.sil b/test/IRGen/sil_linkage.sil index 381e51251fdb6..d5256e11594bf 100644 --- a/test/IRGen/sil_linkage.sil +++ b/test/IRGen/sil_linkage.sil @@ -5,7 +5,8 @@ sil_stage canonical // CHECK: define{{( protected)?}} swiftcc void @public_fragile_function_test() {{.*}} { // CHECK: define{{( protected)?}} swiftcc void @public_transparent_fragile_function_test() {{.*}} { // CHECK: define{{( protected)?}} swiftcc void @public_transparent_function_test() {{.*}} { -// CHECK: define{{( hidden)?}} swiftcc void @hidden_fragile_function_test() {{.*}} { +// CHECK: define hidden swiftcc void @public_non_abi_function_test() {{.*}} { +// CHECK: define hidden swiftcc void @hidden_fragile_function_test() {{.*}} { // CHECK: define linkonce_odr hidden swiftcc void @shared_fragile_function_test() {{.*}} { // CHECK: define{{( internal)?}} swiftcc void @private_fragile_function_test() {{.*}} { // Public external functions are not emitted into clients. @@ -37,6 +38,11 @@ sil public [transparent] @public_transparent_function_test : $@convention(thin) return %0 : $() } +sil non_abi [serialized] @public_non_abi_function_test : $@convention(thin) () -> () { + %0 = tuple() + return %0 : $() +} + sil hidden [serialized] @hidden_fragile_function_test : $@convention(thin) () -> () { %0 = tuple() return %0 : $() @@ -138,6 +144,7 @@ sil public @use_all_symbols : $@convention(thin) () -> () { %0 = function_ref @public_fragile_function_test : $@convention(thin) () -> () %t0 = function_ref @public_transparent_fragile_function_test : $@convention(thin) () -> () %t1 = function_ref @public_transparent_function_test : $@convention(thin) () -> () + %t2 = function_ref @public_non_abi_function_test : $@convention(thin) () -> () %1 = function_ref @hidden_fragile_function_test : $@convention(thin) () -> () %2 = function_ref @shared_fragile_function_test : $@convention(thin) () -> () %3 = function_ref @private_fragile_function_test : $@convention(thin) () -> () diff --git a/test/SIL/Parser/basic.sil b/test/SIL/Parser/basic.sil index 276046ed848c9..d7bdf3308ccd4 100644 --- a/test/SIL/Parser/basic.sil +++ b/test/SIL/Parser/basic.sil @@ -36,22 +36,6 @@ sil_global @static_array : $TestArrayStorage = { %initval = object $TestArrayStorage (%3 : $Int32, [tail_elems] %4 : $Int64, %5 : $Int64) } -// Linkage types. - -// CHECK-LABEL: sil shared @clang_thunk : $@convention(thin) () -> () -sil shared @clang_thunk : $() -> () { -bb0: - %0 = tuple () - return %0 : $() -} - -// CHECK-LABEL: sil private @internal_fn : $@convention(thin) () -> () -sil private @internal_fn : $() -> () { -bb0: - %0 = tuple () - return %0 : $() -} - // Type references // Some cyclic type references between SIL function bodies. diff --git a/test/SIL/Parser/linkage.sil b/test/SIL/Parser/linkage.sil new file mode 100644 index 0000000000000..e3d226bc0993b --- /dev/null +++ b/test/SIL/Parser/linkage.sil @@ -0,0 +1,55 @@ +// RUN: %target-sil-opt %s | %target-sil-opt | %FileCheck %s + +sil_stage raw // CHECK: sil_stage raw + +import Builtin +import Swift + +// CHECK-LABEL: sil @public_definition : $@convention(thin) () -> () +sil @public_definition : $() -> () { +bb0: + %0 = tuple () + return %0 : $() +} + +// CHECK-LABEL: sil non_abi @always_emit_into_client_definition : $@convention(thin) () -> () +sil non_abi @always_emit_into_client_definition : $() -> () { +bb0: + %0 = tuple () + return %0 : $() +} + +// CHECK-LABEL: sil shared @shared_definition : $@convention(thin) () -> () +sil shared @shared_definition : $() -> () { +bb0: + %0 = tuple () + return %0 : $() +} + +// CHECK-LABEL: sil hidden @hidden_definition : $@convention(thin) () -> () +sil hidden @hidden_definition : $() -> () { +bb0: + %0 = tuple () + return %0 : $() +} + +// CHECK-LABEL: sil private @private_definition : $@convention(thin) () -> () +sil private @private_definition : $() -> () { +bb0: + %0 = tuple () + return %0 : $() +} + +// CHECK-LABEL: sil public_external @public_available_externally_definition : $@convention(thin) () -> () +sil public_external @public_available_externally_definition : $() -> () { +bb0: + %0 = tuple () + return %0 : $() +} + +// CHECK-LABEL: sil @public_declaration : $@convention(thin) () -> () +sil @public_declaration : $() -> () + +// CHECK-LABEL: sil hidden_external @hidden_declaration : $@convention(thin) () -> () +sil hidden_external @hidden_declaration : $() -> () + diff --git a/test/SIL/Serialization/Inputs/def_public_non_abi.sil b/test/SIL/Serialization/Inputs/def_public_non_abi.sil new file mode 100644 index 0000000000000..4010b44169adc --- /dev/null +++ b/test/SIL/Serialization/Inputs/def_public_non_abi.sil @@ -0,0 +1,4 @@ +sil non_abi [serialized] @public_non_abi_function : $@convention(thin) () -> () { + %0 = tuple () + return %0 : $() +} \ No newline at end of file diff --git a/test/SIL/Serialization/deserialize_generic.sil b/test/SIL/Serialization/deserialize_generic.sil index 2d118a25c0686..22c7dd8f66b5e 100644 --- a/test/SIL/Serialization/deserialize_generic.sil +++ b/test/SIL/Serialization/deserialize_generic.sil @@ -21,5 +21,5 @@ bb0: } // Make sure the function body is deserialized. -// CHECK-LABEL: @$S11def_generic1AC23convertFromArrayLiteralyACyxGxd_tF : $@convention(method) (@owned Array, @guaranteed A) -> @owned A { +// CHECK-LABEL: sil public_external [serialized] @$S11def_generic1AC23convertFromArrayLiteralyACyxGxd_tF : $@convention(method) (@owned Array, @guaranteed A) -> @owned A { sil @$S11def_generic1AC23convertFromArrayLiteralyACyxGxd_tF : $@convention(method) (@owned Array, @guaranteed A) -> @owned A diff --git a/test/SIL/Serialization/public_non_abi.sil b/test/SIL/Serialization/public_non_abi.sil new file mode 100644 index 0000000000000..6c46ea0d85dce --- /dev/null +++ b/test/SIL/Serialization/public_non_abi.sil @@ -0,0 +1,25 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_public_non_abi.sil +// RUN: %target-sil-opt -linker -I %t %s | %FileCheck %s + +sil_stage raw + +import def_public_non_abi +import Builtin +import Swift + +// CHECK-LABEL: sil @top_level_code +// CHECK: function_ref @public_non_abi_function : $@convention(thin) () -> () +// CHECK: return + +sil @top_level_code : $@convention(thin) () -> () { +bb0: + %0 = function_ref @public_non_abi_function : $@convention(thin) () -> () + %1 = tuple () + return %1 : $() +} + +// Make sure the function body is deserialized. +// CHECK-LABEL: sil shared_external [serialized] @public_non_abi_function : $@convention(thin) () -> () +// CHECK: return +sil hidden_external [serialized] @public_non_abi_function : $@convention(thin) () -> () diff --git a/test/SILGen/default_arguments_serialized.swift b/test/SILGen/default_arguments_serialized.swift index a63384fe517c3..0172a9cfd0531 100644 --- a/test/SILGen/default_arguments_serialized.swift +++ b/test/SILGen/default_arguments_serialized.swift @@ -15,10 +15,10 @@ import default_arguments_other public func defaultString() -> String { return "hi" } // SWIFT3-LABEL: sil @$S28default_arguments_serialized19hasDefaultArguments1x1yySi_SStFfA_ : $@convention(thin) () -> Int -// SWIFT4-LABEL: sil [serialized] @$S28default_arguments_serialized19hasDefaultArguments1x1yySi_SStFfA_ : $@convention(thin) () -> Int +// SWIFT4-LABEL: sil non_abi [serialized] @$S28default_arguments_serialized19hasDefaultArguments1x1yySi_SStFfA_ : $@convention(thin) () -> Int // SWIFT3-LABEL: sil @$S28default_arguments_serialized19hasDefaultArguments1x1yySi_SStFfA0_ : $@convention(thin) () -> @owned String -// SWIFT4-LABEL: sil [serialized] @$S28default_arguments_serialized19hasDefaultArguments1x1yySi_SStFfA0_ : $@convention(thin) () -> @owned String +// SWIFT4-LABEL: sil non_abi [serialized] @$S28default_arguments_serialized19hasDefaultArguments1x1yySi_SStFfA0_ : $@convention(thin) () -> @owned String public func hasDefaultArguments(x: Int = 0, y: String = defaultString()) {} @@ -55,7 +55,7 @@ public func callsOtherDefaultArguments() { otherDefaultArguments() } -// CHECK-LABEL: sil [serialized] @$S23default_arguments_other0C16DefaultArguments1xySi_tFfA_ : $@convention(thin) () -> Int +// CHECK-LABEL: sil hidden_external [serialized] @$S23default_arguments_other0C16DefaultArguments1xySi_tFfA_ : $@convention(thin) () -> Int // CHECK-LABEL: sil @$S23default_arguments_other0C16DefaultArguments1xySi_tF : $@convention(thin) (Int) -> () diff --git a/test/SILGen/fixed_layout_attribute.swift b/test/SILGen/fixed_layout_attribute.swift index 0e8e067ab2316..cb46889b5a3de 100644 --- a/test/SILGen/fixed_layout_attribute.swift +++ b/test/SILGen/fixed_layout_attribute.swift @@ -20,7 +20,7 @@ public struct NonFixedStruct { public var storedProperty = global } -// CHECK-LABEL: sil [transparent] @$S22fixed_layout_attribute14NonFixedStructV14storedPropertySivpfi : $@convention(thin) () -> Int +// CHECK-LABEL: sil hidden [transparent] @$S22fixed_layout_attribute14NonFixedStructV14storedPropertySivpfi : $@convention(thin) () -> Int // // ... okay to directly reference the addressor here: // CHECK: function_ref @$S22fixed_layout_attribute6globalSivau @@ -31,7 +31,7 @@ public struct FixedStruct { public var storedProperty = global } -// CHECK-LABEL: sil [transparent] [serialized] @$S22fixed_layout_attribute11FixedStructV14storedPropertySivpfi : $@convention(thin) () -> Int +// CHECK-LABEL: sil non_abi [transparent] [serialized] @$S22fixed_layout_attribute11FixedStructV14storedPropertySivpfi : $@convention(thin) () -> Int // // ... a fragile build can still reference the addressor: // FRAGILE: function_ref @$S22fixed_layout_attribute6globalSivau diff --git a/test/SILGen/inlineable_attribute.swift b/test/SILGen/inlineable_attribute.swift index ee46ec92bf31d..564b5b5bcbb20 100644 --- a/test/SILGen/inlineable_attribute.swift +++ b/test/SILGen/inlineable_attribute.swift @@ -49,10 +49,13 @@ public class MyCls { _ = MyEnum.c } -// CHECK-LABEL: sil [transparent] @$S20inlineable_attribute15HasInitializersV1xSivpfi : $@convention(thin) () -> Int +// CHECK-LABEL: sil non_abi [transparent] [serialized] @$S20inlineable_attribute15HasInitializersV1xSivpfi : $@convention(thin) () -> Int +// CHECK-LABEL: sil non_abi [transparent] [serialized] @$S20inlineable_attribute15HasInitializersV1ySivpfi : $@convention(thin) () -> Int +@_fixed_layout public struct HasInitializers { public let x = 1234 + internal let y = 4321 @_inlineable public init() {} } diff --git a/test/SILOptimizer/globalopt_linkage.swift b/test/SILOptimizer/globalopt_linkage.swift index af505f14f75e5..ebd9fa7c8d09f 100644 --- a/test/SILOptimizer/globalopt_linkage.swift +++ b/test/SILOptimizer/globalopt_linkage.swift @@ -9,9 +9,11 @@ struct MyStruct { let Global = 27 func testit() -> Int { - return MyStruct.StaticVar + Global + return MyStruct.StaticVar + Global + PublicGlobal } +public let PublicGlobal = 27 + _ = testit() // CHECK: sil hidden @{{.*}}testit @@ -21,3 +23,6 @@ _ = testit() // CHECK: // Global.getter // CHECK-NEXT: sil private @$S{{.*}}Global + +// CHECK: // PublicGlobal.getter +// CHECK-NEXT: sil non_abi @$S{{.*}}PublicGlobal diff --git a/test/TBD/function.swift b/test/TBD/function.swift index 765cadd3b9337..f2974ae0a0583 100644 --- a/test/TBD/function.swift +++ b/test/TBD/function.swift @@ -1,4 +1,5 @@ -// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=all %s +// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=all -swift-version 3 %s +// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=all -swift-version 4 %s public func publicNoArgs() {} public func publicSomeArgs(_: Int, x: Int) {} diff --git a/test/multifile/default-arguments/one-module/Inputs/library.swift b/test/multifile/default-arguments/one-module/Inputs/library.swift new file mode 100644 index 0000000000000..faeedc8c4a554 --- /dev/null +++ b/test/multifile/default-arguments/one-module/Inputs/library.swift @@ -0,0 +1,2 @@ +public func publicHasDefaultArgument(x: Int = 0) {} +internal func internalHasDefaultArgument(x: Int = 0) {} diff --git a/test/multifile/default-arguments/one-module/main.swift b/test/multifile/default-arguments/one-module/main.swift new file mode 100644 index 0000000000000..b935ac010adac --- /dev/null +++ b/test/multifile/default-arguments/one-module/main.swift @@ -0,0 +1,10 @@ +// Try with and without whole module optimization, Swift 3 and Swift 4 mode + +// RUN: %target-build-swift -swift-version 3 %S/Inputs/library.swift %S/main.swift +// RUN: %target-build-swift -swift-version 3 -whole-module-optimization %S/Inputs/library.swift %S/main.swift + +// RUN: %target-build-swift -swift-version 4 %S/Inputs/library.swift %S/main.swift +// RUN: %target-build-swift -swift-version 4 -whole-module-optimization %S/Inputs/library.swift %S/main.swift + +publicHasDefaultArgument() +internalHasDefaultArgument() diff --git a/test/multifile/default-arguments/two-modules/Inputs/library.swift b/test/multifile/default-arguments/two-modules/Inputs/library.swift new file mode 100644 index 0000000000000..2e7fe3d0de846 --- /dev/null +++ b/test/multifile/default-arguments/two-modules/Inputs/library.swift @@ -0,0 +1 @@ +public func hasDefaultArgument(x: Int = 0) {} diff --git a/test/multifile/default-arguments/two-modules/main.swift b/test/multifile/default-arguments/two-modules/main.swift new file mode 100644 index 0000000000000..0c6ac5c06c0c6 --- /dev/null +++ b/test/multifile/default-arguments/two-modules/main.swift @@ -0,0 +1,19 @@ +// RUN: %empty-directory(%t) + +// RUN: mkdir -p %t/onone %t/wmo +// RUN: %target-build-swift -emit-module -emit-module-path %t/onone/library.swiftmodule -module-name=library -emit-library %S/Inputs/library.swift -o %t/onone/library.%target-dylib-extension -swift-version 3 +// RUN: %target-build-swift %S/main.swift %t/onone/library.%target-dylib-extension -I %t/onone/ -o %t/onone/main -swift-version 3 + +// RUN: %target-build-swift -emit-module -emit-module-path %t/wmo/library.swiftmodule -module-name=library -emit-library -O -wmo %S/Inputs/library.swift -o %t/wmo/library.%target-dylib-extension -swift-version 3 +// RUN: %target-build-swift %S/main.swift %t/wmo/library.%target-dylib-extension -I %t/wmo/ -o %t/wmo/main -swift-version 3 + +// RUN: mkdir -p %t/onone %t/wmo +// RUN: %target-build-swift -emit-module -emit-module-path %t/onone/library.swiftmodule -module-name=library -emit-library %S/Inputs/library.swift -o %t/onone/library.%target-dylib-extension -swift-version 4 +// RUN: %target-build-swift %S/main.swift %t/onone/library.%target-dylib-extension -I %t/onone/ -o %t/onone/main -swift-version 4 + +// RUN: %target-build-swift -emit-module -emit-module-path %t/wmo/library.swiftmodule -module-name=library -emit-library -O -wmo %S/Inputs/library.swift -o %t/wmo/library.%target-dylib-extension -swift-version 4 +// RUN: %target-build-swift %S/main.swift %t/wmo/library.%target-dylib-extension -I %t/wmo/ -o %t/wmo/main -swift-version 4 + +import library + +hasDefaultArgument() diff --git a/validation-test/Evolution/Inputs/change_default_argument_to_magic.swift b/validation-test/Evolution/Inputs/change_default_argument_to_magic.swift new file mode 100644 index 0000000000000..24d765753b2cf --- /dev/null +++ b/validation-test/Evolution/Inputs/change_default_argument_to_magic.swift @@ -0,0 +1,10 @@ + +#if BEFORE + +public func changeDefaultArgumentToMagic(name: String = "hello") {} + +#else + +public func changeDefaultArgumentToMagic(name: String = #file) {} + +#endif diff --git a/validation-test/Evolution/test_change_default_argument_to_magic.swift b/validation-test/Evolution/test_change_default_argument_to_magic.swift new file mode 100644 index 0000000000000..730d0ba6afada --- /dev/null +++ b/validation-test/Evolution/test_change_default_argument_to_magic.swift @@ -0,0 +1,14 @@ +// RUN: %target-resilience-test +// REQUIRES: executable_test + +import StdlibUnittest +import change_default_argument_to_magic + + +var ChangeDefaultArgumentToMagic = TestSuite("ChangeDefaultArgumentToMagic") + +ChangeDefaultArgumentToMagic.test("ChangeDefaultArgumentToMagic") { + changeDefaultArgumentToMagic() +} + +runAllTests()