Skip to content

Commit bc0d474

Browse files
authored
Merge pull request #80833 from xedin/print-supported-features
[Frontend] Add a way to print features supported by the compiler
2 parents 493e853 + 18703d6 commit bc0d474

15 files changed

+199
-50
lines changed

include/swift/Basic/FileTypes.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ TYPE("fine-module-trace", FineModuleTrace, "", "")
7878
// Complete dependency information for the given Swift files as JSON.
7979
TYPE("json-dependencies", JSONDependencies, "dependencies.json", "")
8080

81-
// Complete feature information for the given Swift compiler.
82-
TYPE("json-features", JSONFeatures, "features.json", "")
81+
// Complete supported argument information for the given Swift compiler.
82+
TYPE("json-arguments", JSONArguments, "arguments.json", "")
8383

8484
// Gathered compile-time-known value information for the given Swift input file as JSON.
8585
TYPE("const-values", ConstValues, "swiftconstvalues", "")
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===--- SupportedFeatures.h - Supported Features Output --------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file provides a high-level API for supported features info
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_SUPPORTEDFEATURES_H
18+
#define SWIFT_SUPPORTEDFEATURES_H
19+
20+
#include "swift/Basic/LLVM.h"
21+
22+
namespace swift {
23+
namespace features {
24+
void printSupportedFeatures(llvm::raw_ostream &out);
25+
} // namespace features
26+
} // namespace swift
27+
28+
#endif

include/swift/Frontend/FrontendOptions.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ class FrontendOptions {
201201

202202
ScanDependencies, ///< Scan dependencies of Swift source files
203203
PrintVersion, ///< Print version information.
204-
PrintFeature, ///< Print supported feature of this compiler
204+
PrintArguments, ///< Print supported arguments of this compiler
205205
};
206206

207207
/// Indicates the action the user requested that the frontend perform.
@@ -314,6 +314,10 @@ class FrontendOptions {
314314
/// exit.
315315
bool PrintTargetInfo = false;
316316

317+
/// Indicates that the frontend should print the supported features and then
318+
/// exit.
319+
bool PrintSupportedFeatures = false;
320+
317321
/// See the \ref SILOptions.EmitVerboseSIL flag.
318322
bool EmitVerboseSIL = false;
319323

include/swift/Option/Options.td

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,6 +1534,10 @@ def print_target_info : Flag<["-"], "print-target-info">,
15341534
Flags<[FrontendOption]>,
15351535
HelpText<"Print target information for the given target <triple>, such as x86_64-apple-macos10.9">, MetaVarName<"<triple>">;
15361536

1537+
def print_supported_features : Flag<["-"], "print-supported-features">,
1538+
Flags<[FrontendOption]>,
1539+
HelpText<"Print information about features supported by the compiler">;
1540+
15371541
def target_cpu : Separate<["-"], "target-cpu">, Flags<[FrontendOption, ModuleInterfaceOption]>,
15381542
HelpText<"Generate code for a particular CPU variant">;
15391543

@@ -1650,9 +1654,13 @@ def scan_dependencies : Flag<["-"], "scan-dependencies">,
16501654
HelpText<"Scan dependencies of the given Swift sources">, ModeOpt,
16511655
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>;
16521656

1653-
def emit_supported_features : Flag<["-"], "emit-supported-features">,
1654-
HelpText<"Emit a JSON file including all supported compiler features">, ModeOpt,
1657+
def emit_supported_arguments : Flag<["-"], "emit-supported-arguments">,
1658+
HelpText<"Emit a JSON file including all supported compiler arguments">, ModeOpt,
16551659
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>;
1660+
def emit_supported_features : Flag<["-"], "emit-supported-features">,
1661+
HelpText<"This is a compatibility alias for '-emit-supported-arguments'">, ModeOpt,
1662+
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild, HelpHidden]>,
1663+
Alias<emit_supported_arguments>;
16561664

16571665
def enable_incremental_imports :
16581666
Flag<["-"], "enable-incremental-imports">,

lib/Basic/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ add_swift_host_library(swiftBasic STATIC
7575
StableHasher.cpp
7676
Statistic.cpp
7777
StringExtras.cpp
78+
SupportedFeatures.cpp
7879
TargetInfo.cpp
7980
TaskQueue.cpp
8081
ThreadSafeRefCounted.cpp

lib/Basic/FileTypes.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ bool file_types::isTextual(ID Id) {
112112
case file_types::TY_PackageSwiftModuleInterfaceFile:
113113
case file_types::TY_SwiftOverlayFile:
114114
case file_types::TY_JSONDependencies:
115-
case file_types::TY_JSONFeatures:
115+
case file_types::TY_JSONArguments:
116116
case file_types::TY_SwiftABIDescriptor:
117117
case file_types::TY_SwiftAPIDescriptor:
118118
case file_types::TY_ConstValues:
@@ -195,7 +195,7 @@ bool file_types::isAfterLLVM(ID Id) {
195195
case file_types::TY_PrivateSwiftModuleInterfaceFile:
196196
case file_types::TY_PackageSwiftModuleInterfaceFile:
197197
case file_types::TY_JSONDependencies:
198-
case file_types::TY_JSONFeatures:
198+
case file_types::TY_JSONArguments:
199199
case file_types::TY_IndexUnitOutputPath:
200200
case file_types::TY_SwiftABIDescriptor:
201201
case file_types::TY_SwiftAPIDescriptor:
@@ -257,7 +257,7 @@ bool file_types::isPartOfSwiftCompilation(ID Id) {
257257
case file_types::TY_YAMLOptRecord:
258258
case file_types::TY_BitstreamOptRecord:
259259
case file_types::TY_JSONDependencies:
260-
case file_types::TY_JSONFeatures:
260+
case file_types::TY_JSONArguments:
261261
case file_types::TY_IndexUnitOutputPath:
262262
case file_types::TY_SwiftABIDescriptor:
263263
case file_types::TY_SwiftAPIDescriptor:
@@ -321,7 +321,7 @@ bool file_types::isProducedFromDiagnostics(ID Id) {
321321
case file_types::TY_YAMLOptRecord:
322322
case file_types::TY_BitstreamOptRecord:
323323
case file_types::TY_JSONDependencies:
324-
case file_types::TY_JSONFeatures:
324+
case file_types::TY_JSONArguments:
325325
case file_types::TY_IndexUnitOutputPath:
326326
case file_types::TY_SwiftABIDescriptor:
327327
case file_types::TY_SwiftAPIDescriptor:

lib/Basic/SupportedFeatures.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//===--- SupportedFeatures.cpp - Supported features printing --------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include <array>
14+
#include <vector>
15+
16+
#include "swift/Basic/Feature.h"
17+
#include "swift/Frontend/Frontend.h"
18+
19+
#include "llvm/Support/raw_ostream.h"
20+
21+
using namespace swift;
22+
23+
namespace swift {
24+
namespace features {
25+
/// Print information about what features upcoming/experimental are
26+
/// supported by the compiler.
27+
/// The information includes whether a feature is adoptable and for
28+
/// upcoming features - what is the first mode it's introduced.
29+
void printSupportedFeatures(llvm::raw_ostream &out) {
30+
std::array upcoming{
31+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description)
32+
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) Feature::FeatureName,
33+
#include "swift/Basic/Features.def"
34+
};
35+
36+
std::vector<swift::Feature> experimental{{
37+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description)
38+
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) Feature::FeatureName,
39+
#include "swift/Basic/Features.def"
40+
}};
41+
42+
// Include only experimental features that are available in production.
43+
llvm::erase_if(experimental, [](auto &feature) {
44+
return feature.isAvailableInProduction();
45+
});
46+
47+
out << "{\n";
48+
auto printFeature = [&out](const Feature &feature) {
49+
out << " ";
50+
out << "{ \"name\": \"" << feature.getName() << "\"";
51+
if (feature.isAdoptable()) {
52+
out << ", \"migratable\": true";
53+
}
54+
if (auto version = feature.getLanguageVersion()) {
55+
out << ", \"enabled_in\": " << *version;
56+
}
57+
out << " }";
58+
};
59+
60+
out << " \"features\": {\n";
61+
out << " \"upcoming\": [\n";
62+
llvm::interleave(upcoming, printFeature, [&out] { out << ",\n"; });
63+
out << "\n ],\n";
64+
65+
out << " \"experimental\": [\n";
66+
llvm::interleave(experimental, printFeature, [&out] { out << ",\n"; });
67+
out << "\n ]\n";
68+
69+
out << " }\n";
70+
out << "}\n";
71+
}
72+
73+
} // end namespace features
74+
} // end namespace swift

lib/Driver/Driver.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1708,7 +1708,7 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
17081708
case file_types::TY_SwiftCrossImportDir:
17091709
case file_types::TY_SwiftOverlayFile:
17101710
case file_types::TY_JSONDependencies:
1711-
case file_types::TY_JSONFeatures:
1711+
case file_types::TY_JSONArguments:
17121712
case file_types::TY_SwiftABIDescriptor:
17131713
case file_types::TY_SwiftAPIDescriptor:
17141714
case file_types::TY_ConstValues:
@@ -2049,6 +2049,28 @@ bool Driver::handleImmediateArgs(const ArgList &Args, const ToolChain &TC) {
20492049
return false;
20502050
}
20512051

2052+
if (Args.hasArg(options::OPT_print_supported_features)) {
2053+
SmallVector<const char *, 5> commandLine;
2054+
commandLine.push_back("-frontend");
2055+
commandLine.push_back("-print-supported-features");
2056+
2057+
std::string executable = getSwiftProgramPath();
2058+
2059+
// FIXME(https://github.com/apple/swift/issues/54554): This bypasses
2060+
// mechanisms like -v and -###.
2061+
sys::TaskQueue queue;
2062+
queue.addTask(executable.c_str(), commandLine);
2063+
queue.execute(nullptr,
2064+
[](sys::ProcessId PID, int returnCode, StringRef output,
2065+
StringRef errors, sys::TaskProcessInformation ProcInfo,
2066+
void *unused) -> sys::TaskFinishedResponse {
2067+
llvm::outs() << output;
2068+
llvm::errs() << errors;
2069+
return sys::TaskFinishedResponse::ContinueExecution;
2070+
});
2071+
return false;
2072+
}
2073+
20522074
return true;
20532075
}
20542076

lib/Driver/ToolChains.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,8 @@ const char *ToolChain::JobContext::computeFrontendModeForCompile() const {
754754
return "-emit-imported-modules";
755755
case file_types::TY_JSONDependencies:
756756
return "-scan-dependencies";
757-
case file_types::TY_JSONFeatures:
758-
return "-emit-supported-features";
757+
case file_types::TY_JSONArguments:
758+
return "-emit-supported-arguments";
759759
case file_types::TY_IndexData:
760760
return "-typecheck";
761761
case file_types::TY_Remapping:
@@ -1041,7 +1041,7 @@ ToolChain::constructInvocation(const BackendJobAction &job,
10411041
case file_types::TY_ClangModuleFile:
10421042
case file_types::TY_IndexData:
10431043
case file_types::TY_JSONDependencies:
1044-
case file_types::TY_JSONFeatures:
1044+
case file_types::TY_JSONArguments:
10451045
llvm_unreachable("Cannot be output from backend job");
10461046
case file_types::TY_Swift:
10471047
case file_types::TY_dSYM:

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ bool ArgsToFrontendOptionsConverter::convert(
206206
Opts.PrintTargetInfo = true;
207207
}
208208

209+
if (Args.hasArg(OPT_print_supported_features)) {
210+
Opts.PrintSupportedFeatures = true;
211+
}
212+
209213
if (const Arg *A = Args.getLastArg(OPT_verify_generic_signatures)) {
210214
Opts.VerifyGenericSignaturesInModule = A->getValue();
211215
}
@@ -678,8 +682,8 @@ ArgsToFrontendOptionsConverter::determineRequestedAction(const ArgList &args) {
678682
return FrontendOptions::ActionType::CompileModuleFromInterface;
679683
if (Opt.matches(OPT_typecheck_module_from_interface))
680684
return FrontendOptions::ActionType::TypecheckModuleFromInterface;
681-
if (Opt.matches(OPT_emit_supported_features))
682-
return FrontendOptions::ActionType::PrintFeature;
685+
if (Opt.matches(OPT_emit_supported_arguments))
686+
return FrontendOptions::ActionType::PrintArguments;
683687
llvm_unreachable("Unhandled mode option");
684688
}
685689

lib/Frontend/ArgsToFrontendOutputsConverter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ static bool shouldEmitFineModuleTrace(FrontendOptions::ActionType action) {
451451
case swift::FrontendOptions::ActionType::DumpPCM:
452452
case swift::FrontendOptions::ActionType::ScanDependencies:
453453
case swift::FrontendOptions::ActionType::PrintVersion:
454-
case swift::FrontendOptions::ActionType::PrintFeature:
454+
case swift::FrontendOptions::ActionType::PrintArguments:
455455
return false;
456456
}
457457
}

0 commit comments

Comments
 (0)