Skip to content

Commit 4cac784

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 - Allow all unicode characters in package-name input string Resolves rdar://107638447, rdar://104617274
1 parent 4cbd4a1 commit 4cac784

10 files changed

+96
-18
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; do not pass the flag if unused",
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/Frontend/CompilerInvocation.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,11 @@ static void SaveModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
401401
return;
402402
ArgStringList RenderedArgs;
403403
ArgStringList RenderedArgsIgnorable;
404+
ArgStringList RenderedArgsIgnorablePrivate;
404405
for (auto A : Args) {
405-
if (A->getOption().hasFlag(options::ModuleInterfaceOptionIgnorable)) {
406+
if (A->getOption().hasFlag(options::ModuleInterfaceOptionIgnorablePrivate)) {
407+
A->render(Args, RenderedArgsIgnorablePrivate);
408+
} else if (A->getOption().hasFlag(options::ModuleInterfaceOptionIgnorable)) {
406409
A->render(Args, RenderedArgsIgnorable);
407410
} else if (A->getOption().hasFlag(options::ModuleInterfaceOption)) {
408411
A->render(Args, RenderedArgs);
@@ -421,6 +424,12 @@ static void SaveModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
421424
if (FOpts.ModuleName == "_Concurrency")
422425
OS << " -disable-availability-checking";
423426
}
427+
{
428+
llvm::raw_string_ostream OS(Opts.IgnorablePrivateFlags);
429+
interleave(RenderedArgsIgnorablePrivate,
430+
[&](const char *Argument) { PrintArg(OS, Argument, StringRef()); },
431+
[&] { OS << " "; });
432+
}
424433
{
425434
llvm::raw_string_ostream OS(Opts.IgnorableFlags);
426435
interleave(RenderedArgsIgnorable,
@@ -796,10 +805,11 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
796805

797806
if (const Arg *A = Args.getLastArg(OPT_package_name)) {
798807
auto pkgName = A->getValue();
799-
if (!Lexer::isIdentifier(pkgName))
800-
Diags.diagnose(SourceLoc(), diag::error_bad_package_name, pkgName);
808+
auto str = StringRef(pkgName);
809+
if (str.empty())
810+
Diags.diagnose(SourceLoc(), diag::error_empty_package_name);
801811
else
802-
Opts.PackageName = pkgName;
812+
Opts.PackageName = pkgName; //QuotedString(pkgName).getString();
803813
}
804814

805815
if (const Arg *A = Args.getLastArg(OPT_require_explicit_availability_EQ)) {

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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
// RUN: %FileCheck %s -check-prefix CHECK-UTILS < %t/Utils.swiftinterface
1212
// CHECK-UTILS: -module-name Utils -enable-library-evolution
13-
// CHECK-UTILS: swift-module-flags-ignorable: -package-name myLib
13+
// CHECK-UTILS-NOT: -package-name myLib
1414
// CHECK-UTILS: @usableFromInline
1515
// CHECK-UTILS: package class PackageKlassProto {
1616
// CHECK-UTILS: @usableFromInline
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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 myLib
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 -enable-library-evolution
15+
// CHECK-PUBLIC-NOT: -package-name myLib
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 myLib
23+
// CHECK-PRIVATE: public func publicFunc()
24+
// CHECK-PRIVATE: package func packageFunc()
25+
26+
27+
// RUN: %target-swift-frontend -emit-module %t/UtilsPkg.swift \
28+
// RUN: -module-name UtilsPkg -swift-version 5 -I %t \
29+
// RUN: -package-name "ab \\n cd"
30+
// RUN: -enable-library-evolution \
31+
// RUN: -emit-module-path %t/UtilsPkg.swiftmodule \
32+
// RUN: -emit-module-interface-path %t/UtilsPkg.swiftinterface \
33+
// RUN: -emit-private-module-interface-path %t/UtilsPkg.private.swiftinterface
34+
35+
// RUN: %target-swift-typecheck-module-from-interface(%t/UtilsPkg.private.swiftinterface) -module-name Utils -I %t
36+
// RUN: %FileCheck %s --check-prefix=CHECK-PRIVATE-PKG < %t/UtilsPkg.private.swiftinterface
37+
// CHECK-PRIVATE-PKG: swift-module-flags-ignorable-private: -package-name "ab \n cd"
38+
39+
// RUN: %target-swift-frontend -typecheck %t/Client.swift -package-nname "ab \\n cd" -verify
40+
41+
42+
//--- Utils.swift
43+
package func packageFunc() {}
44+
public func publicFunc() {}
45+
46+
//--- Client.swift
47+
import UtilsPkg
48+
49+
func clientFunc() {
50+
packageFunc()
51+
publicFunc()
52+
}
Lines changed: 6 additions & 7 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; do not pass the flag if unused
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,10 @@
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

20+
// Package name can have any unicode characters
21+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name My-Logging%Pkg
22+
// RUN: %target-swift-frontend %s -typecheck -verify -package-name "a \\n b"
23+
// RUN: %target-swift-frontend %s -module-name Logging -package-name "a \bc \n \r de-f.g ~!@ #$ %^& *() -+ [] {} <> ,?/ | :" -emit-module -emit-module-path %t/Logging.swiftmodule -verify
24+
2625
package func log() {}
2726

0 commit comments

Comments
 (0)