Skip to content

Commit 03e0006

Browse files
committed
ModuleInterface: move -user-module-version to a new field
Titled as "// swift-module-flags-ignorable:", this new field contains new frontend arguments that can be safely ignored by the older version of the compiler. For compilers that don't know the field at all, all arguments in it are ignored. rdar://78233352
1 parent 53264a6 commit 03e0006

File tree

7 files changed

+78
-6
lines changed

7 files changed

+78
-6
lines changed

include/swift/Frontend/ModuleInterfaceSupport.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define SWIFT_INTERFACE_FORMAT_VERSION_KEY "swift-interface-format-version"
2121
#define SWIFT_COMPILER_VERSION_KEY "swift-compiler-version"
2222
#define SWIFT_MODULE_FLAGS_KEY "swift-module-flags"
23+
#define SWIFT_MODULE_FLAGS_IGNORABLE_KEY "swift-module-flags-ignorable"
2324

2425
namespace swift {
2526

@@ -41,6 +42,10 @@ struct ModuleInterfaceOptions {
4142
/// back .swiftinterface and reconstructing .swiftmodule.
4243
std::string Flags;
4344

45+
/// Flags that should be emitted to the .swiftinterface file but are OK to be
46+
/// ignored by the earlier version of the compiler.
47+
std::string IgnorableFlags;
48+
4449
/// Print SPI decls and attributes.
4550
bool PrintSPIs = false;
4651

include/swift/Option/Options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ namespace options {
4141
SwiftSymbolGraphExtractOption = (1 << 16),
4242
SwiftAPIDigesterOption = (1 << 17),
4343
NewDriverOnlyOption = (1 << 18),
44+
ModuleInterfaceOptionIgnorable = (1 << 19),
4445
};
4546

4647
enum ID {

include/swift/Option/Options.td

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ def ArgumentIsPath : OptionFlag;
5151
// and read/parsed from there when reconstituting a .swiftmodule from it.
5252
def ModuleInterfaceOption : OptionFlag;
5353

54+
// The option should be written into a .swiftinterface module interface file,
55+
// and read/parsed from there when reconstituting a .swiftmodule from it.
56+
// The option can be safely ignored by the older compiler.
57+
def ModuleInterfaceOptionIgnorable : OptionFlag;
58+
5459
// The option causes the output of a supplementary output, or is the path option
5560
// for a supplementary output. E.g., `-emit-module` and `-emit-module-path`.
5661
def SupplementaryOutput : OptionFlag;
@@ -1184,7 +1189,7 @@ def working_directory_EQ : Joined<["-"], "working-directory=">,
11841189
Alias<working_directory>;
11851190

11861191
def user_module_version : Separate<["-"], "user-module-version">,
1187-
Flags<[FrontendOption, ModuleInterfaceOption, NewDriverOnlyOption]>,
1192+
Flags<[FrontendOption, ModuleInterfaceOptionIgnorable, NewDriverOnlyOption]>,
11881193
HelpText<"Module version specified from Swift module authors">,
11891194
MetaVarName<"<vers>">;
11901195

lib/Frontend/CompilerInvocation.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -355,14 +355,26 @@ static void SaveModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
355355
if (!FOpts.InputsAndOutputs.hasModuleInterfaceOutputPath())
356356
return;
357357
ArgStringList RenderedArgs;
358+
ArgStringList RenderedArgsIgnorable;
358359
for (auto A : Args) {
359-
if (A->getOption().hasFlag(options::ModuleInterfaceOption))
360+
if (A->getOption().hasFlag(options::ModuleInterfaceOptionIgnorable)) {
361+
A->render(Args, RenderedArgsIgnorable);
362+
} else if (A->getOption().hasFlag(options::ModuleInterfaceOption)) {
360363
A->render(Args, RenderedArgs);
364+
}
365+
}
366+
{
367+
llvm::raw_string_ostream OS(Opts.Flags);
368+
interleave(RenderedArgs,
369+
[&](const char *Argument) { PrintArg(OS, Argument, StringRef()); },
370+
[&] { OS << " "; });
371+
}
372+
{
373+
llvm::raw_string_ostream OS(Opts.IgnorableFlags);
374+
interleave(RenderedArgsIgnorable,
375+
[&](const char *Argument) { PrintArg(OS, Argument, StringRef()); },
376+
[&] { OS << " "; });
361377
}
362-
llvm::raw_string_ostream OS(Opts.Flags);
363-
interleave(RenderedArgs,
364-
[&](const char *Argument) { PrintArg(OS, Argument, StringRef()); },
365-
[&] { OS << " "; });
366378
}
367379

368380
static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ static void printToolVersionAndFlagsComment(raw_ostream &out,
5656
<< ToolsVersion << "\n";
5757
out << "// " SWIFT_MODULE_FLAGS_KEY ": "
5858
<< Opts.Flags << "\n";
59+
if (!Opts.IgnorableFlags.empty()) {
60+
out << "// " SWIFT_MODULE_FLAGS_IGNORABLE_KEY ": "
61+
<< Opts.IgnorableFlags << "\n";
62+
}
5963
}
6064

6165
std::string

lib/Serialization/SerializedModuleLoader.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@
2222
#include "swift/Basic/STLExtras.h"
2323
#include "swift/Basic/SourceManager.h"
2424
#include "swift/Basic/Version.h"
25+
#include "swift/Option/Options.h"
2526

27+
#include "llvm/Option/OptTable.h"
28+
#include "llvm/Option/ArgList.h"
2629
#include "llvm/ADT/SmallString.h"
2730
#include "llvm/ADT/StringSet.h"
2831
#include "llvm/Support/Debug.h"
@@ -970,6 +973,33 @@ bool swift::extractCompilerFlagsFromInterface(StringRef buffer,
970973
return true;
971974
assert(FlagMatches.size() == 2);
972975
llvm::cl::TokenizeGNUCommandLine(FlagMatches[1], ArgSaver, SubArgs);
976+
SmallVector<StringRef, 1> IgnFlagMatches;
977+
// Cherry-pick supported options from the ignorable list.
978+
auto IgnFlagRe = llvm::Regex("^// swift-module-flags-ignorable:(.*)$",
979+
llvm::Regex::Newline);
980+
// It's OK the interface doesn't have the ignorable list, we just ignore them
981+
// all.
982+
if (!IgnFlagRe.match(buffer, &IgnFlagMatches))
983+
return false;
984+
SmallVector<const char *, 8> IgnSubArgs;
985+
llvm::cl::TokenizeGNUCommandLine(IgnFlagMatches[1], ArgSaver, IgnSubArgs);
986+
std::unique_ptr<llvm::opt::OptTable> table = swift::createSwiftOptTable();
987+
unsigned missingArgIdx = 0;
988+
unsigned missingArgCount = 0;
989+
auto parsedIgns = table->ParseArgs(IgnSubArgs, missingArgIdx, missingArgCount);
990+
for (auto parse: parsedIgns) {
991+
// Check if the option is a frontend option. This will filter out unknown
992+
// options and input-like options.
993+
if (!parse->getOption().hasFlag(options::FrontendOption))
994+
continue;
995+
// Push the supported option and its value to the list.
996+
// We shouldn't need to worry about cases like -tbd-install_name=Foo because
997+
// the parsing function should have droped alias options already.
998+
SubArgs.push_back(ArgSaver.save(parse->getSpelling()).data());
999+
for (auto value: parse->getValues())
1000+
SubArgs.push_back(value);
1001+
}
1002+
9731003
return false;
9741004
}
9751005

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/textual)
3+
// RUN: %empty-directory(%t/module-cache)
4+
5+
// RUN: echo "// swift-interface-format-version: 1.0" > %t/textual/Foo.swiftinterface
6+
// RUN: echo "// swift-module-flags: -swift-version 5 -enable-library-evolution -module-name Foo" >> %t/textual/Foo.swiftinterface
7+
8+
// RUN: %target-swift-ide-test -print-module-metadata -module-to-print Foo -I %t/textual -source-filename %s -module-cache-path %t/module-cache | %FileCheck %s --check-prefix=USER-MODULE-PRINT-NOT
9+
10+
// RUN: echo "// swift-module-flags-ignorable: -enable-library-evolution -user-module-version 13.13 -future-flag1 3 -future-flag2 abc -future-flag3 /tmp/t.swift /tmp/u.swift -tbd-install_name=aaa" >> %t/textual/Foo.swiftinterface
11+
12+
// RUN: %target-swift-ide-test -print-module-metadata -module-to-print Foo -I %t/textual -source-filename %s -module-cache-path %t/module-cache | %FileCheck %s --check-prefix=USER-MODULE-PRINT
13+
14+
// USER-MODULE-PRINT-NOT-NOT: user module version: 13.13.0.0
15+
// USER-MODULE-PRINT: user module version: 13.13.0.0

0 commit comments

Comments
 (0)