Skip to content

Commit f6e30ea

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 a28b729 commit f6e30ea

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
@@ -475,6 +475,10 @@ static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
475475
/// Checks if an arg is generally allowed to be included
476476
/// in a module interface
477477
static bool ShouldIncludeModuleInterfaceArg(const Arg *A) {
478+
if (!A->getOption().hasFlag(options::ModuleInterfaceOption) &&
479+
!A->getOption().hasFlag(options::ModuleInterfaceOptionIgnorable))
480+
return false;
481+
478482
if (!A->getOption().matches(options::OPT_enable_experimental_feature))
479483
return true;
480484

@@ -499,43 +503,47 @@ static void SaveModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
499503
ArgList &Args, DiagnosticEngine &Diags) {
500504
if (!FOpts.InputsAndOutputs.hasModuleInterfaceOutputPath())
501505
return;
502-
503-
ArgStringList RenderedArgs;
504-
ArgStringList RenderedArgsForPackageOnly;
505-
ArgStringList RenderedArgsIgnorable;
506+
507+
struct RenderedInterfaceArgs {
508+
ArgStringList Standard = {};
509+
ArgStringList Ignorable = {};
510+
};
511+
512+
RenderedInterfaceArgs PublicArgs{};
513+
RenderedInterfaceArgs PackageArgs{};
514+
515+
auto interfaceArgListForArg = [&](Arg *A) -> ArgStringList & {
516+
bool ignorable =
517+
A->getOption().hasFlag(options::ModuleInterfaceOptionIgnorable);
518+
if (ShouldIncludeArgInPackageInterfaceOnly(A, Args))
519+
return ignorable ? PackageArgs.Ignorable : PackageArgs.Standard;
520+
521+
return ignorable ? PublicArgs.Ignorable : PublicArgs.Standard;
522+
};
506523

507524
for (auto A : Args) {
508525
if (!ShouldIncludeModuleInterfaceArg(A))
509526
continue;
510527

511-
if (A->getOption().hasFlag(options::ModuleInterfaceOptionIgnorable)) {
512-
A->render(Args, RenderedArgsIgnorable);
513-
} else if (A->getOption().hasFlag(options::ModuleInterfaceOption)) {
514-
if (ShouldIncludeArgInPackageInterfaceOnly(A, Args))
515-
A->render(Args, RenderedArgsForPackageOnly);
516-
else
517-
A->render(Args, RenderedArgs);
518-
}
519-
}
520-
{
521-
llvm::raw_string_ostream OS(Opts.Flags);
522-
interleave(RenderedArgs,
523-
[&](const char *Argument) { PrintArg(OS, Argument, StringRef()); },
524-
[&] { OS << " "; });
525-
}
526-
{
527-
llvm::raw_string_ostream OS(Opts.FlagsForPackageOnly);
528-
interleave(
529-
RenderedArgsForPackageOnly,
530-
[&](const char *Argument) { PrintArg(OS, Argument, StringRef()); },
531-
[&] { OS << " "; });
532-
}
533-
{
534-
llvm::raw_string_ostream OS(Opts.IgnorableFlags);
535-
interleave(RenderedArgsIgnorable,
536-
[&](const char *Argument) { PrintArg(OS, Argument, StringRef()); },
537-
[&] { OS << " "; });
538-
}
528+
ArgStringList &ArgList = interfaceArgListForArg(A);
529+
A->render(Args, ArgList);
530+
}
531+
532+
auto updateInterfaceOpts = [](ModuleInterfaceOptions::InterfaceFlags &Flags,
533+
RenderedInterfaceArgs &RenderedArgs) {
534+
auto printFlags = [](std::string &str, ArgStringList argList) {
535+
llvm::raw_string_ostream OS(str);
536+
interleave(
537+
argList,
538+
[&](const char *Argument) { PrintArg(OS, Argument, StringRef()); },
539+
[&] { OS << " "; });
540+
};
541+
printFlags(Flags.Flags, RenderedArgs.Standard);
542+
printFlags(Flags.IgnorableFlags, RenderedArgs.Ignorable);
543+
};
544+
545+
updateInterfaceOpts(Opts.PublicFlags, PublicArgs);
546+
updateInterfaceOpts(Opts.PackageFlags, PackageArgs);
539547
}
540548

541549
enum class CxxCompatMode {

lib/Frontend/ModuleInterfaceSupport.cpp

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

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

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

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

113114
std::string

0 commit comments

Comments
 (0)