Skip to content

Commit b1418f6

Browse files
committed
Frontend: Refactor how flags are saved for module interfaces.
There are two axes on which a saved frontend flag can be categorized for printing in a `.swiftinterface` file: 1. Whether the flag is "ignorable" or not. 2. Which levels of interface the flag should be in (public, package). This refactor ensures that those two axes are modeled independently and prepares the infrastructure to allow flags to appear in the private and package interfaces without being included in the public interface.
1 parent 03c8ccb commit b1418f6

File tree

3 files changed

+67
-55
lines changed

3 files changed

+67
-55
lines changed

include/swift/Frontend/ModuleInterfaceSupport.h

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,22 @@ struct ModuleInterfaceOptions {
4141
/// [TODO: Clang-type-plumbing] This check should go away.
4242
bool PrintFullConvention = false;
4343

44-
/// Copy of all the command-line flags passed at .swiftinterface
45-
/// generation time, re-applied to CompilerInvocation when reading
46-
/// back .swiftinterface and reconstructing .swiftmodule.
47-
std::string Flags;
48-
49-
/// Keep track of flags to be printed in package.swiftinterface only.
50-
/// If -disable-print-package-name-for-non-package-interface is passed,
51-
/// package-name flag should only be printed in package.swiftinterface.
52-
std::string FlagsForPackageOnly;
53-
54-
/// Flags that should be emitted to the .swiftinterface file but are OK to be
55-
/// ignored by the earlier version of the compiler.
56-
std::string IgnorableFlags;
44+
struct InterfaceFlags {
45+
/// Copy of all the command-line flags passed at .swiftinterface
46+
/// generation time, re-applied to CompilerInvocation when reading
47+
/// back .swiftinterface and reconstructing .swiftmodule.
48+
std::string Flags = "";
49+
50+
/// Flags that should be emitted to the .swiftinterface file but are OK to
51+
/// be ignored by the earlier version of the compiler.
52+
std::string IgnorableFlags = "";
53+
};
54+
55+
/// Flags which appear in all .swiftinterface files.
56+
InterfaceFlags PublicFlags = {};
57+
58+
/// Flags which appear only in the .package.swiftinterface.
59+
InterfaceFlags PackageFlags = {};
5760

5861
/// Print imports with both @_implementationOnly and @_spi, only applies
5962
/// when PrintSPIs is true.

lib/Frontend/CompilerInvocation.cpp

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,10 @@ static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
435435
/// Checks if an arg is generally allowed to be included
436436
/// in a module interface
437437
static bool ShouldIncludeModuleInterfaceArg(const Arg *A) {
438+
if (!A->getOption().hasFlag(options::ModuleInterfaceOption) &&
439+
!A->getOption().hasFlag(options::ModuleInterfaceOptionIgnorable))
440+
return false;
441+
438442
if (!A->getOption().matches(options::OPT_enable_experimental_feature))
439443
return true;
440444

@@ -459,43 +463,47 @@ static void SaveModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
459463
ArgList &Args, DiagnosticEngine &Diags) {
460464
if (!FOpts.InputsAndOutputs.hasModuleInterfaceOutputPath())
461465
return;
462-
463-
ArgStringList RenderedArgs;
464-
ArgStringList RenderedArgsForPackageOnly;
465-
ArgStringList RenderedArgsIgnorable;
466+
467+
struct RenderedInterfaceArgs {
468+
ArgStringList Standard = {};
469+
ArgStringList Ignorable = {};
470+
};
471+
472+
RenderedInterfaceArgs PublicArgs{};
473+
RenderedInterfaceArgs PackageArgs{};
474+
475+
auto interfaceArgListForArg = [&](Arg *A) -> ArgStringList & {
476+
bool ignorable =
477+
A->getOption().hasFlag(options::ModuleInterfaceOptionIgnorable);
478+
if (ShouldIncludeArgInPackageInterfaceOnly(A, Args))
479+
return ignorable ? PackageArgs.Ignorable : PackageArgs.Standard;
480+
481+
return ignorable ? PublicArgs.Ignorable : PublicArgs.Standard;
482+
};
466483

467484
for (auto A : Args) {
468485
if (!ShouldIncludeModuleInterfaceArg(A))
469486
continue;
470487

471-
if (A->getOption().hasFlag(options::ModuleInterfaceOptionIgnorable)) {
472-
A->render(Args, RenderedArgsIgnorable);
473-
} else if (A->getOption().hasFlag(options::ModuleInterfaceOption)) {
474-
if (ShouldIncludeArgInPackageInterfaceOnly(A, Args))
475-
A->render(Args, RenderedArgsForPackageOnly);
476-
else
477-
A->render(Args, RenderedArgs);
478-
}
479-
}
480-
{
481-
llvm::raw_string_ostream OS(Opts.Flags);
482-
interleave(RenderedArgs,
483-
[&](const char *Argument) { PrintArg(OS, Argument, StringRef()); },
484-
[&] { OS << " "; });
485-
}
486-
{
487-
llvm::raw_string_ostream OS(Opts.FlagsForPackageOnly);
488-
interleave(
489-
RenderedArgsForPackageOnly,
490-
[&](const char *Argument) { PrintArg(OS, Argument, StringRef()); },
491-
[&] { OS << " "; });
492-
}
493-
{
494-
llvm::raw_string_ostream OS(Opts.IgnorableFlags);
495-
interleave(RenderedArgsIgnorable,
496-
[&](const char *Argument) { PrintArg(OS, Argument, StringRef()); },
497-
[&] { OS << " "; });
498-
}
488+
ArgStringList &ArgList = interfaceArgListForArg(A);
489+
A->render(Args, ArgList);
490+
}
491+
492+
auto updateInterfaceOpts = [](ModuleInterfaceOptions::InterfaceFlags &Flags,
493+
RenderedInterfaceArgs &RenderedArgs) {
494+
auto printFlags = [](std::string &str, ArgStringList argList) {
495+
llvm::raw_string_ostream OS(str);
496+
interleave(
497+
argList,
498+
[&](const char *Argument) { PrintArg(OS, Argument, StringRef()); },
499+
[&] { OS << " "; });
500+
};
501+
printFlags(Flags.Flags, RenderedArgs.Standard);
502+
printFlags(Flags.IgnorableFlags, RenderedArgs.Ignorable);
503+
};
504+
505+
updateInterfaceOpts(Opts.PublicFlags, PublicArgs);
506+
updateInterfaceOpts(Opts.PackageFlags, PackageArgs);
499507
}
500508

501509
enum class CxxCompatMode {

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,12 @@ static void printToolVersionAndFlagsComment(raw_ostream &out,
5959
<< InterfaceFormatVersion << "\n";
6060
out << "// " SWIFT_COMPILER_VERSION_KEY ": "
6161
<< ToolsVersion << "\n";
62-
out << "// " SWIFT_MODULE_FLAGS_KEY ": "
63-
<< Opts.Flags;
62+
out << "// " SWIFT_MODULE_FLAGS_KEY ": " << Opts.PublicFlags.Flags;
6463

65-
// Adding package-name can be disabled in non-package
66-
// swiftinterfaces; add only to package.swiftinterface
67-
// in such case.
68-
if (Opts.printPackageInterface() &&
69-
!Opts.FlagsForPackageOnly.empty())
70-
out << " " << Opts.FlagsForPackageOnly;
64+
// Append flags that are for the package interface only (e.g. -package-name
65+
// when -disable-print-package-name-for-non-package-interface is specified).
66+
if (Opts.printPackageInterface() && !Opts.PackageFlags.Flags.empty())
67+
out << " " << Opts.PackageFlags.Flags;
7168

7269
// Insert additional -module-alias flags
7370
if (Opts.AliasModuleNames) {
@@ -103,10 +100,14 @@ static void printToolVersionAndFlagsComment(raw_ostream &out,
103100
}
104101
out << "\n";
105102

106-
if (!Opts.IgnorableFlags.empty()) {
103+
if (!Opts.PublicFlags.IgnorableFlags.empty()) {
107104
out << "// " SWIFT_MODULE_FLAGS_IGNORABLE_KEY ": "
108-
<< Opts.IgnorableFlags << "\n";
105+
<< Opts.PublicFlags.IgnorableFlags << "\n";
109106
}
107+
108+
// Append ignorable flags that are for the package interface only.
109+
if (Opts.printPackageInterface() && !Opts.PackageFlags.IgnorableFlags.empty())
110+
out << " " << Opts.PackageFlags.IgnorableFlags;
110111
}
111112

112113
std::string

0 commit comments

Comments
 (0)