Skip to content

Commit 08332b7

Browse files
committed
- Introduce an option to print flags only for .private.swiftinterface
- Print package name flag only in private interface as package symbols are not exported in public interface - If package decls are in public interface, they are inlinable so treated as public - Allow all unicode characters in package-name input string Resolves rdar://107638447, rdar://104617274
1 parent 347e565 commit 08332b7

13 files changed

+150
-35
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,9 @@ ERROR(error_bad_export_as_name,none,
189189
"export-as name \"%0\" is not a valid identifier",
190190
(StringRef))
191191

192-
ERROR(error_bad_package_name,none,
193-
"package name \"%0\" is not a valid identifier",
194-
(StringRef))
192+
ERROR(error_empty_package_name,none,
193+
"package-name is empty",
194+
())
195195
ERROR(error_stdlib_not_found,Fatal,
196196
"unable to load standard library for target '%0'", (StringRef))
197197
ERROR(error_module_alias_invalid_format,none,

include/swift/Frontend/ModuleInterfaceSupport.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define SWIFT_COMPILER_VERSION_KEY "swift-compiler-version"
2222
#define SWIFT_MODULE_FLAGS_KEY "swift-module-flags"
2323
#define SWIFT_MODULE_FLAGS_IGNORABLE_KEY "swift-module-flags-ignorable"
24+
#define SWIFT_MODULE_FLAGS_IGNORABLE_PRIVATE_KEY "swift-module-flags-ignorable-private"
2425

2526
namespace swift {
2627

@@ -50,6 +51,10 @@ struct ModuleInterfaceOptions {
5051
/// ignored by the earlier version of the compiler.
5152
std::string IgnorableFlags;
5253

54+
/// Ignorable flags that should only be printed in .private.swiftinterface file;
55+
/// e.g. -package-name PACKAGE_ID
56+
std::string IgnorablePrivateFlags;
57+
5358
/// Print for a private swiftinterface file, SPI decls and attributes.
5459
bool PrintPrivateInterfaceContent = false;
5560

include/swift/Option/Options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ namespace options {
4242
SwiftAPIDigesterOption = (1 << 17),
4343
NewDriverOnlyOption = (1 << 18),
4444
ModuleInterfaceOptionIgnorable = (1 << 19),
45+
ModuleInterfaceOptionIgnorablePrivate = (1 << 20),
4546
};
4647

4748
enum ID {

include/swift/Option/Options.td

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ def ModuleInterfaceOption : OptionFlag;
5656
// The option can be safely ignored by the older compiler.
5757
def ModuleInterfaceOptionIgnorable : OptionFlag;
5858

59+
// The option should be written into a .private.swiftinterface module interface file,
60+
// and read/parsed from there when reconstituting a .swiftmodule from it.
61+
// The option can be safely ignored by the older compiler.
62+
def ModuleInterfaceOptionIgnorablePrivate : OptionFlag;
63+
5964
// The option causes the output of a supplementary output, or is the path option
6065
// for a supplementary output. E.g., `-emit-module` and `-emit-module-path`.
6166
def SupplementaryOutput : OptionFlag;
@@ -530,7 +535,7 @@ def module_abi_name : Separate<["-"], "module-abi-name">,
530535
Flags<[FrontendOption, ModuleInterfaceOption]>,
531536
HelpText<"ABI name to use for the contents of this module">;
532537
def package_name : Separate<["-"], "package-name">,
533-
Flags<[FrontendOption, ModuleInterfaceOptionIgnorable]>,
538+
Flags<[FrontendOption, ModuleInterfaceOptionIgnorablePrivate]>,
534539
HelpText<"Name of the package the module belongs to">;
535540
def export_as : Separate<["-"], "export-as">,
536541
Flags<[FrontendOption, ModuleInterfaceOptionIgnorable]>,

lib/AST/Decl.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3939,11 +3939,17 @@ getAccessScopeForFormalAccess(const ValueDecl *VD,
39393939
case AccessLevel::Package: {
39403940
auto pkg = resultDC->getPackageContext(/*lookupIfNotCurrent*/ true);
39413941
if (!pkg) {
3942-
// No package context was found; show diagnostics
3943-
auto &d = VD->getASTContext().Diags;
3944-
d.diagnose(VD->getLoc(), diag::access_control_requires_package_name);
3945-
// Instead of reporting and failing early, return the scope of
3946-
// resultDC to allow continuation (should still non-zero exit later)
3942+
auto sourceContext = dyn_cast<SourceFile>(resultDC->getModuleScopeContext());
3943+
// Check if the file containing package acl is a source file, not an interface;
3944+
// if interface, package decls must be inlinable, essentially public; show
3945+
// diagnostics only if it's a source file (script mode).
3946+
if (sourceContext && sourceContext->isScriptMode()) {
3947+
// No package context was found; show diagnostics
3948+
auto &d = VD->getASTContext().Diags;
3949+
d.diagnose(VD->getLoc(), diag::access_control_requires_package_name);
3950+
// Instead of reporting and failing early, return the scope of
3951+
// resultDC to allow continuation (should still non-zero exit later)
3952+
}
39473953
return AccessScope(resultDC);
39483954
} else {
39493955
return AccessScope(pkg);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -426,8 +426,11 @@ static void SaveModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
426426
return;
427427
ArgStringList RenderedArgs;
428428
ArgStringList RenderedArgsIgnorable;
429+
ArgStringList RenderedArgsIgnorablePrivate;
429430
for (auto A : Args) {
430-
if (A->getOption().hasFlag(options::ModuleInterfaceOptionIgnorable)) {
431+
if (A->getOption().hasFlag(options::ModuleInterfaceOptionIgnorablePrivate)) {
432+
A->render(Args, RenderedArgsIgnorablePrivate);
433+
} else if (A->getOption().hasFlag(options::ModuleInterfaceOptionIgnorable)) {
431434
A->render(Args, RenderedArgsIgnorable);
432435
} else if (A->getOption().hasFlag(options::ModuleInterfaceOption)) {
433436
A->render(Args, RenderedArgs);
@@ -446,6 +449,12 @@ static void SaveModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
446449
if (FOpts.ModuleName == "_Concurrency")
447450
OS << " -disable-availability-checking";
448451
}
452+
{
453+
llvm::raw_string_ostream OS(Opts.IgnorablePrivateFlags);
454+
interleave(RenderedArgsIgnorablePrivate,
455+
[&](const char *Argument) { PrintArg(OS, Argument, StringRef()); },
456+
[&] { OS << " "; });
457+
}
449458
{
450459
llvm::raw_string_ostream OS(Opts.IgnorableFlags);
451460
interleave(RenderedArgsIgnorable,
@@ -821,8 +830,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
821830

822831
if (const Arg *A = Args.getLastArg(OPT_package_name)) {
823832
auto pkgName = A->getValue();
824-
if (!Lexer::isIdentifier(pkgName))
825-
Diags.diagnose(SourceLoc(), diag::error_bad_package_name, pkgName);
833+
auto str = StringRef(pkgName);
834+
if (str.empty())
835+
Diags.diagnose(SourceLoc(), diag::error_empty_package_name);
826836
else
827837
Opts.PackageName = pkgName;
828838
}

lib/Frontend/Frontend.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,8 +1155,8 @@ ModuleDecl *CompilerInstance::getMainModule() const {
11551155
Invocation.getFrontendOptions().ModuleABIName));
11561156
}
11571157
if (!Invocation.getLangOptions().PackageName.empty()) {
1158-
MainModule->setPackageName(getASTContext().getIdentifier(
1159-
Invocation.getLangOptions().PackageName));
1158+
auto pkgName = Invocation.getLangOptions().PackageName;
1159+
MainModule->setPackageName(getASTContext().getIdentifier(pkgName));
11601160
}
11611161
if (!Invocation.getFrontendOptions().ExportAsName.empty()) {
11621162
MainModule->setExportAsName(getASTContext().getIdentifier(

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ static void printToolVersionAndFlagsComment(raw_ostream &out,
9898
out << "// " SWIFT_MODULE_FLAGS_IGNORABLE_KEY ": "
9999
<< Opts.IgnorableFlags << "\n";
100100
}
101+
102+
auto hasPrivateIgnorableFlags = Opts.PrintPrivateInterfaceContent && !Opts.IgnorablePrivateFlags.empty();
103+
if (hasPrivateIgnorableFlags) {
104+
out << "// " SWIFT_MODULE_FLAGS_IGNORABLE_PRIVATE_KEY ": "
105+
<< Opts.IgnorablePrivateFlags << "\n";
106+
}
101107
}
102108

103109
std::string

test/Sema/accessibility_package_inline_interface.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
// RUN: %target-swift-typecheck-module-from-interface(%t/Utils.swiftinterface) -I%t
1010

1111
// RUN: %FileCheck %s -check-prefix CHECK-UTILS < %t/Utils.swiftinterface
12-
// CHECK-UTILS: -module-name Utils -enable-library-evolution
13-
// CHECK-UTILS: swift-module-flags-ignorable: -package-name myLib
12+
// CHECK-UTILS: -module-name Utils
13+
// CHECK-UTILS-NOT: -package-name myLib
1414
// CHECK-UTILS: @usableFromInline
1515
// CHECK-UTILS: package class PackageKlassProto {
1616
// CHECK-UTILS: @usableFromInline
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -emit-module %t/Utils.swift \
5+
// RUN: -module-name Utils -swift-version 5 -I %t \
6+
// RUN: -package-name swift-utils.log \
7+
// RUN: -enable-library-evolution \
8+
// RUN: -emit-module-path %t/Utils.swiftmodule \
9+
// RUN: -emit-module-interface-path %t/Utils.swiftinterface \
10+
// RUN: -emit-private-module-interface-path %t/Utils.private.swiftinterface
11+
12+
// RUN: %target-swift-typecheck-module-from-interface(%t/Utils.swiftinterface) -I %t
13+
// RUN: %FileCheck %s --check-prefix=CHECK-PUBLIC < %t/Utils.swiftinterface
14+
// CHECK-PUBLIC: -module-name Utils
15+
// CHECK-PUBLIC-NOT: -package-name swift-utils.log
16+
// CHECK-PUBLIC: public func publicFunc()
17+
// CHECK-PUBLIC-NOT: package func packageFunc()
18+
19+
// RUN: %target-swift-typecheck-module-from-interface(%t/Utils.private.swiftinterface) -module-name Utils -I %t
20+
// RUN: %FileCheck %s --check-prefix=CHECK-PRIVATE < %t/Utils.private.swiftinterface
21+
22+
// CHECK-PRIVATE: swift-module-flags-ignorable-private: -package-name swift-utils.log
23+
// CHECK-PRIVATE: public func publicFunc()
24+
// CHECK-PRIVATE-NOT: package func packageFunc()
25+
26+
// RUN: %target-swift-frontend -typecheck %t/Client.swift -package-name swift-utils.log -verify
27+
28+
//--- Utils.swift
29+
package func packageFunc() {}
30+
public func publicFunc() {}
31+
32+
//--- Client.swift
33+
import Utils
34+
35+
func clientFunc() {
36+
packageFunc()
37+
publicFunc()
38+
}

test/Serialization/load_package_module.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
// RUN: %empty-directory(%t)
22
// RUN: split-file %s %t
33

4-
// RUN: %target-swift-frontend -module-name LibFromInterface -emit-module -emit-module-interface-path %t/LibFromInterface.swiftinterface -parse-as-library %t/Lib.swift -enable-library-evolution -package-name mypkg -swift-version 5
5-
// RUN: test -f %t/LibFromInterface.swiftinterface
6-
// RUN: %FileCheck %s -check-prefix CHECK-LIB < %t/LibFromInterface.swiftinterface
7-
// CHECK-LIB: -package-name mypkg
8-
// CHECK-LIB-NOT: func log(level: Int)
4+
// RUN: %target-swift-frontend -module-name LibFromInterface -emit-module -emit-module-interface-path %t/LibFromInterface.swiftinterface -emit-private-module-interface-path %t/LibFromInterface.private.swiftinterface -parse-as-library %t/Lib.swift -enable-library-evolution -package-name mypkg -swift-version 5
5+
6+
// RUN: %target-swift-typecheck-module-from-interface(%t/LibFromInterface.swiftinterface) -I %t
7+
// RUN: %FileCheck %s --check-prefix=CHECK-PUBLIC < %t/LibFromInterface.swiftinterface
8+
// CHECK-PUBLIC: -module-name LibFromInterface
9+
// CHECK-PUBLIC-NOT: -package-name mypkg
10+
// CHECK-PUBLIC-NOT: func log(level: Int)
11+
12+
// RUN: %target-swift-typecheck-module-from-interface(%t/LibFromInterface.private.swiftinterface) -I %t
13+
// RUN: %FileCheck %s --check-prefix=CHECK-PRIVATE < %t/LibFromInterface.private.swiftinterface
14+
// CHECK-PRIVATE: swift-module-flags-ignorable-private: -package-name mypkg
15+
// CHECK-PRIVATE: func log(level: Int)
916

1017
// RUN: not %target-swift-frontend -module-name ClientInSamePkg %t/ClientLoadInterfaceModule.swift -emit-module -emit-module-path %t/ClientInSamePkg.swiftmodule -package-name mypkg -I %t 2> %t/resultA.output
1118
// RUN: %FileCheck %s -check-prefix CHECK-A < %t/resultA.output
Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %{python} %utils/split_file.py -o %t %s
2+
// RUN: split-file %s %t
33

44
// RUN: %target-swift-frontend -module-name Logging -package-name MyLoggingPkg %t/File.swift -emit-module -emit-module-path %t/Logging.swiftmodule
55
// RUN: test -f %t/Logging.swiftmodule
66
// RUN: llvm-bcanalyzer -dump %t/Logging.swiftmodule | %FileCheck %s -check-prefix CHECK-BLOB
77
// CHECK-BLOB: <MODULE_PACKAGE_NAME abbrevid=5/> blob data = 'MyLoggingPkg'
88

9-
// RUN: %target-swift-frontend -module-name Logging -package-name MyLoggingPkg %t/File.swift -emit-module -emit-module-interface-path %t/Logging.swiftinterface -swift-version 5 -enable-library-evolution -I %t
10-
// RUN: test -f %t/Logging.swiftinterface
11-
// RUN: %FileCheck %s -input-file %t/Logging.swiftinterface -check-prefix CHECK-FLAG
12-
// CHECK-FLAG: -package-name MyLoggingPkg
9+
// RUN: %target-swift-frontend -module-name Logging -package-name MyLoggingPkg %t/File.swift -emit-module -emit-module-interface-path %t/Logging.swiftinterface -emit-private-module-interface-path %t/Logging.private.swiftinterface -swift-version 5 -enable-library-evolution -I %t
1310

14-
// BEGIN File.swift
11+
// RUN: %target-swift-typecheck-module-from-interface(%t/Logging.swiftinterface) -I %t
12+
// RUN: %FileCheck %s --check-prefix=CHECK-PUBLIC < %t/Logging.swiftinterface
13+
// CHECK-PUBLIC: -module-name Logging
14+
// CHECK-PUBLIC-NOT: -package-name
15+
16+
// RUN: %target-swift-typecheck-module-from-interface(%t/Logging.private.swiftinterface) -module-name Logging -I %t
17+
// RUN: %FileCheck %s --check-prefix=CHECK-PRIVATE < %t/Logging.private.swiftinterface
18+
// CHECK-PRIVATE: -module-name Logging
19+
// CHECK-PRIVATE: swift-module-flags-ignorable-private: -package-name MyLoggingPkg
20+
21+
//--- File.swift
1522
public func log(level: Int) {}
Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
// RUN: %empty-directory(%t)
22

3-
// Package name should have valid characters
4-
// RUN: not %target-swift-frontend -module-name Logging -package-name My-Logging%Pkg %s -emit-module -emit-module-path %t/Logging.swiftmodule 2> %t/resultA.output
5-
// RUN: %FileCheck %s -input-file %t/resultA.output -check-prefix CHECK-BAD
6-
// CHECK-BAD: error: package name "My-Logging%Pkg" is not a valid identifier
7-
// CHECK-BAD: error: decl has a package access level but no -package-name was passed
8-
93
// Package name should not be empty
104
// RUN: not %target-swift-frontend -typecheck %s -package-name "" 2>&1 | %FileCheck %s -check-prefix CHECK-EMPTY
11-
// CHECK-EMPTY: error: package name "" is not a valid identifier
5+
// CHECK-EMPTY: error: package-name is empty
126
// CHECK-EMPTY: error: decl has a package access level but no -package-name was passed
137

148
// If package access level is used but no package-name is passed, it should error
@@ -23,5 +17,41 @@
2317
// RUN: %target-swift-frontend -module-name Logging -package-name Swift %s -emit-module -emit-module-path %t/Logging.swiftmodule
2418
// RUN: test -f %t/Logging.swiftmodule
2519

26-
package func log() {}
20+
// Package name can have any unicode characters
21+
22+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name " "
23+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name swift-util.log
24+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name swift$util.log
25+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name swift\$util.log
26+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name swift*util.log
27+
28+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name -swift*util.log
29+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name .swift*util-log
30+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name \#swift#utillog
31+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name swift^util\&lo\(g+@
32+
33+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name swift-util$tools*log
34+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name swift/utils/tools/log.git
35+
36+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name "foo bar baz git"
37+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name My-Logging%Pkg
2738

39+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name Προϊόν
40+
41+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name \n
42+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name “\n”
43+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name \\n
44+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name “\\n”
45+
46+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name “
47+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name ‘
48+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name \‘
49+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name \\‘
50+
51+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name \”
52+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name \\”
53+
54+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name "a \\n b"
55+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name "a \n de-f.g ~!@#$%^&<>?/|:"
56+
57+
package func log() {}

0 commit comments

Comments
 (0)