Skip to content

Commit 7583511

Browse files
committed
[Sema] Allow the use of SPI in API for SPI modules
When the whole module has an SPI distribution, SPI declarations can be used in API. rdar://75335462
1 parent 091e5af commit 7583511

File tree

6 files changed

+48
-5
lines changed

6 files changed

+48
-5
lines changed

lib/Frontend/CompilerInvocation.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,13 @@ static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
331331
Args.hasArg(OPT_experimental_spi_imports);
332332
Opts.DebugPrintInvalidSyntax |=
333333
Args.hasArg(OPT_debug_emit_invalid_swiftinterface_syntax);
334+
335+
if (const Arg *A = Args.getLastArg(OPT_library_level)) {
336+
StringRef contents = A->getValue();
337+
if (contents == "spi") {
338+
Opts.PrintSPIs = true;
339+
}
340+
}
334341
}
335342

336343
/// Save a copy of any flags marked as ModuleInterfaceOption, if running

lib/FrontendTool/FrontendTool.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,7 @@ static bool emitAnyWholeModulePostTypeCheckSupplementaryOutputs(
862862
}
863863

864864
if (opts.InputsAndOutputs.hasPrivateModuleInterfaceOutputPath()) {
865-
// Copy the settings from the module interface
865+
// Copy the settings from the module interface to add SPI printing.
866866
ModuleInterfaceOptions privOpts = Invocation.getModuleInterfaceOptions();
867867
privOpts.PrintSPIs = true;
868868

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ ExportContext ExportContext::forDeclSignature(Decl *D) {
179179
(Ctx.LangOpts.DisableAvailabilityChecking
180180
? AvailabilityContext::alwaysAvailable()
181181
: TypeChecker::overApproximateAvailabilityAtLocation(D->getEndLoc(), DC));
182-
bool spi = false;
182+
bool spi = Ctx.LangOpts.LibraryLevel == LibraryLevel::SPI;
183183
bool implicit = false;
184184
bool deprecated = false;
185185
Optional<PlatformKind> unavailablePlatformKind;
@@ -208,7 +208,7 @@ ExportContext ExportContext::forFunctionBody(DeclContext *DC, SourceLoc loc) {
208208
? AvailabilityContext::alwaysAvailable()
209209
: TypeChecker::overApproximateAvailabilityAtLocation(loc, DC));
210210

211-
bool spi = false;
211+
bool spi = Ctx.LangOpts.LibraryLevel == LibraryLevel::SPI;
212212
bool implicit = false;
213213
bool deprecated = false;
214214
Optional<PlatformKind> unavailablePlatformKind;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/// Check that SPI declarations can be exported from an SPI module.
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: %target-typecheck-verify-swift -I %t -verify-ignore-unknown -enable-library-evolution -swift-version 5 -library-level spi
5+
6+
@_spi(S) public func spiFunc() {}
7+
@_spi(S) public class SPIClass {
8+
public init() {}
9+
}
10+
@_spi(S) public class SPIStruct {
11+
public init() {}
12+
}
13+
@_spi(S) public protocol SPIProtocol {}
14+
15+
public func useOfSPITypeOk(_ p0: SPIProtocol, p1: SPIClass) -> SPIClass { fatalError() }
16+
17+
@inlinable
18+
func inlinable() -> SPIClass {
19+
spiFunc()
20+
_ = SPIClass()
21+
}
22+
23+
@frozen public struct FrozenStruct {
24+
public var spiInFrozen = SPIStruct()
25+
var spiTypeInFrozen = SPIStruct()
26+
private var spiTypeInFrozen1: SPIClass
27+
}

test/SPI/private_swiftinterface.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@
4242
// RUN: %target-swift-frontend -typecheck-module-from-interface -I %t %t/Merged.swiftinterface
4343
// RUN: %target-swift-frontend -typecheck-module-from-interface -I %t %t/Merged.private.swiftinterface -module-name Merged
4444

45+
/// Both the public and private textual interfaces should have
46+
/// SPI information with `-library-level spi`.
47+
// RUN: %target-swift-frontend -typecheck %s -emit-module-interface-path %t/SPIModule.swiftinterface -emit-private-module-interface-path %t/SPIModule.private.swiftinterface -enable-library-evolution -swift-version 5 -I %t -module-name SPIModule -library-level spi
48+
// RUN: %FileCheck -check-prefix=CHECK-PRIVATE %s < %t/SPIModule.swiftinterface
49+
// RUN: %FileCheck -check-prefix=CHECK-PRIVATE %s < %t/SPIModule.private.swiftinterface
50+
// RUN: %target-swift-frontend -typecheck-module-from-interface -I %t %t/SPIModule.swiftinterface
51+
// RUN: %target-swift-frontend -typecheck-module-from-interface -I %t %t/SPIModule.private.swiftinterface -module-name SPIModule
52+
4553
@_spi(HelperSPI) @_spi(OtherSPI) @_spi(OtherSPI) import SPIHelper
4654
// CHECK-PUBLIC: import SPIHelper
4755
// CHECK-PRIVATE: @_spi(OtherSPI) @_spi(HelperSPI) import SPIHelper

test/SPI/public_client.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
// RUN: rm %t/SPIHelper.swiftmodule
1313
// RUN: %target-typecheck-verify-swift -I %t -verify-ignore-unknown
1414

15-
/// Reading from .swiftinterface should still produce the same failures
15+
/// Reading from the public .swiftinterface should raise errors on missing
16+
/// declarations.
1617
// RUN: rm %t/SPIHelper.private.swiftinterface
17-
// RUN: not %target-swift-frontend -typecheck -I %t
18+
// RUN: not %target-swift-frontend -typecheck -I %t %s
1819

1920
import SPIHelper
2021

0 commit comments

Comments
 (0)