Skip to content

Commit 87f57f9

Browse files
authored
Merge pull request #34645 from nkcsgexi/emit-supported-features
Front-end: add a front-end action to print supported features of the compiler
2 parents 58a88c1 + e4916b8 commit 87f57f9

File tree

10 files changed

+91
-1
lines changed

10 files changed

+91
-1
lines changed

include/swift/Basic/FileTypes.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ TYPE("module-trace", ModuleTrace, "trace.json", "")
7575
// Complete dependency information for the given Swift files as JSON.
7676
TYPE("json-dependencies", JSONDependencies, "dependencies.json", "")
7777

78+
// Complete feature information for the given Swift compiler.
79+
TYPE("json-features", JSONFeatures, "features.json", "")
80+
81+
7882
TYPE("index-data", IndexData, "", "")
7983
TYPE("yaml-opt-record", YAMLOptRecord, "opt.yaml", "")
8084
TYPE("bitstream-opt-record",BitstreamOptRecord, "opt.bitstream", "")

include/swift/Frontend/FrontendOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ class FrontendOptions {
136136
ScanDependencies, ///< Scan dependencies of Swift source files
137137
ScanClangDependencies, ///< Scan dependencies of a Clang module
138138
PrintVersion, ///< Print version information.
139+
PrintFeature, ///< Print supported feature of this compiler
139140
};
140141

141142
/// Indicates the action the user requested that the frontend perform.

include/swift/Option/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,10 @@ def scan_clang_dependencies : Flag<["-"], "scan-clang-dependencies">,
11101110
HelpText<"Scan dependencies of the given Clang module">, ModeOpt,
11111111
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>;
11121112

1113+
def emit_supported_features : Flag<["-"], "emit-supported-features">,
1114+
HelpText<"Emit a JSON file including all supported compiler features">, ModeOpt,
1115+
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>;
1116+
11131117
def disable_parser_lookup : Flag<["-"], "disable-parser-lookup">,
11141118
Flags<[FrontendOption]>,
11151119
HelpText<"Disable parser lookup & use ASTScope lookup only (experimental)">;

lib/Basic/FileTypes.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ bool file_types::isTextual(ID Id) {
8383
case file_types::TY_PrivateSwiftModuleInterfaceFile:
8484
case file_types::TY_SwiftOverlayFile:
8585
case file_types::TY_JSONDependencies:
86+
case file_types::TY_JSONFeatures:
8687
return true;
8788
case file_types::TY_Image:
8889
case file_types::TY_Object:
@@ -155,6 +156,7 @@ bool file_types::isAfterLLVM(ID Id) {
155156
case file_types::TY_SwiftModuleInterfaceFile:
156157
case file_types::TY_PrivateSwiftModuleInterfaceFile:
157158
case file_types::TY_JSONDependencies:
159+
case file_types::TY_JSONFeatures:
158160
return false;
159161
case file_types::TY_INVALID:
160162
llvm_unreachable("Invalid type ID.");
@@ -205,6 +207,7 @@ bool file_types::isPartOfSwiftCompilation(ID Id) {
205207
case file_types::TY_YAMLOptRecord:
206208
case file_types::TY_BitstreamOptRecord:
207209
case file_types::TY_JSONDependencies:
210+
case file_types::TY_JSONFeatures:
208211
return false;
209212
case file_types::TY_INVALID:
210213
llvm_unreachable("Invalid type ID.");

lib/Driver/Driver.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2054,6 +2054,7 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
20542054
case file_types::TY_SwiftCrossImportDir:
20552055
case file_types::TY_SwiftOverlayFile:
20562056
case file_types::TY_JSONDependencies:
2057+
case file_types::TY_JSONFeatures:
20572058
// We could in theory handle assembly or LLVM input, but let's not.
20582059
// FIXME: What about LTO?
20592060
Diags.diagnose(SourceLoc(), diag::error_unexpected_input_file,

lib/Driver/ToolChains.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,8 @@ const char *ToolChain::JobContext::computeFrontendModeForCompile() const {
599599
return "-emit-imported-modules";
600600
case file_types::TY_JSONDependencies:
601601
return "-scan-dependencies";
602+
case file_types::TY_JSONFeatures:
603+
return "-emit-supported-features";
602604
case file_types::TY_IndexData:
603605
return "-typecheck";
604606
case file_types::TY_Remapping:
@@ -870,6 +872,7 @@ ToolChain::constructInvocation(const BackendJobAction &job,
870872
case file_types::TY_ClangModuleFile:
871873
case file_types::TY_IndexData:
872874
case file_types::TY_JSONDependencies:
875+
case file_types::TY_JSONFeatures:
873876
llvm_unreachable("Cannot be output from backend job");
874877
case file_types::TY_Swift:
875878
case file_types::TY_dSYM:

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,8 @@ ArgsToFrontendOptionsConverter::determineRequestedAction(const ArgList &args) {
414414
return FrontendOptions::ActionType::CompileModuleFromInterface;
415415
if (Opt.matches(OPT_typecheck_module_from_interface))
416416
return FrontendOptions::ActionType::TypecheckModuleFromInterface;
417-
417+
if (Opt.matches(OPT_emit_supported_features))
418+
return FrontendOptions::ActionType::PrintFeature;
418419
llvm_unreachable("Unhandled mode option");
419420
}
420421

lib/Frontend/FrontendOptions.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ bool FrontendOptions::needsProperModuleName(ActionType action) {
5656
case ActionType::Immediate:
5757
case ActionType::REPL:
5858
case ActionType::PrintVersion:
59+
case ActionType::PrintFeature:
5960
return false;
6061
case ActionType::EmitAssembly:
6162
case ActionType::EmitIR:
@@ -81,6 +82,7 @@ bool FrontendOptions::shouldActionOnlyParse(ActionType action) {
8182
case ActionType::ScanDependencies:
8283
case ActionType::ScanClangDependencies:
8384
case ActionType::PrintVersion:
85+
case ActionType::PrintFeature:
8486
return true;
8587
default:
8688
return false;
@@ -103,6 +105,7 @@ bool FrontendOptions::doesActionRequireSwiftStandardLibrary(ActionType action) {
103105
case ActionType::DumpPCM:
104106
case ActionType::CompileModuleFromInterface:
105107
case ActionType::TypecheckModuleFromInterface:
108+
case ActionType::PrintFeature:
106109
return false;
107110
case ActionType::ResolveImports:
108111
case ActionType::Typecheck:
@@ -134,6 +137,7 @@ bool FrontendOptions::doesActionRequireInputs(ActionType action) {
134137
switch (action) {
135138
case ActionType::NoneAction:
136139
case ActionType::PrintVersion:
140+
case ActionType::PrintFeature:
137141
return false;
138142
case ActionType::REPL:
139143
case ActionType::Parse:
@@ -175,6 +179,7 @@ bool FrontendOptions::doesActionPerformEndOfPipelineActions(ActionType action) {
175179
switch (action) {
176180
case ActionType::NoneAction:
177181
case ActionType::PrintVersion:
182+
case ActionType::PrintFeature:
178183
case ActionType::EmitPCH:
179184
case ActionType::EmitPCM:
180185
case ActionType::DumpPCM:
@@ -305,6 +310,8 @@ FrontendOptions::formatForPrincipalOutputFileForAction(ActionType action) {
305310
case ActionType::ScanDependencies:
306311
case ActionType::ScanClangDependencies:
307312
return TY_JSONDependencies;
313+
case ActionType::PrintFeature:
314+
return TY_JSONFeatures;
308315
}
309316
llvm_unreachable("unhandled action");
310317
}
@@ -327,6 +334,7 @@ bool FrontendOptions::canActionEmitDependencies(ActionType action) {
327334
case ActionType::REPL:
328335
case ActionType::DumpPCM:
329336
case ActionType::PrintVersion:
337+
case ActionType::PrintFeature:
330338
return false;
331339
case ActionType::ResolveImports:
332340
case ActionType::Typecheck:
@@ -372,6 +380,7 @@ bool FrontendOptions::canActionEmitReferenceDependencies(ActionType action) {
372380
case ActionType::ScanDependencies:
373381
case ActionType::ScanClangDependencies:
374382
case ActionType::PrintVersion:
383+
case ActionType::PrintFeature:
375384
return false;
376385
case ActionType::Typecheck:
377386
case ActionType::MergeModules:
@@ -428,6 +437,7 @@ bool FrontendOptions::canActionEmitModuleSummary(ActionType action) {
428437
case ActionType::MergeModules:
429438
case ActionType::EmitModuleOnly:
430439
case ActionType::PrintVersion:
440+
case ActionType::PrintFeature:
431441
return false;
432442
case ActionType::EmitSIL:
433443
case ActionType::EmitSIB:
@@ -463,6 +473,7 @@ bool FrontendOptions::canActionEmitObjCHeader(ActionType action) {
463473
case ActionType::ScanDependencies:
464474
case ActionType::ScanClangDependencies:
465475
case ActionType::PrintVersion:
476+
case ActionType::PrintFeature:
466477
return false;
467478
case ActionType::Typecheck:
468479
case ActionType::MergeModules:
@@ -502,6 +513,7 @@ bool FrontendOptions::canActionEmitLoadedModuleTrace(ActionType action) {
502513
case ActionType::ScanDependencies:
503514
case ActionType::ScanClangDependencies:
504515
case ActionType::PrintVersion:
516+
case ActionType::PrintFeature:
505517
return false;
506518
case ActionType::ResolveImports:
507519
case ActionType::Typecheck:
@@ -547,6 +559,7 @@ bool FrontendOptions::canActionEmitModule(ActionType action) {
547559
case ActionType::ScanDependencies:
548560
case ActionType::ScanClangDependencies:
549561
case ActionType::PrintVersion:
562+
case ActionType::PrintFeature:
550563
return false;
551564
case ActionType::MergeModules:
552565
case ActionType::EmitModuleOnly:
@@ -592,6 +605,7 @@ bool FrontendOptions::canActionEmitInterface(ActionType action) {
592605
case ActionType::DumpPCM:
593606
case ActionType::ScanDependencies:
594607
case ActionType::ScanClangDependencies:
608+
case ActionType::PrintFeature:
595609
return false;
596610
case ActionType::Typecheck:
597611
case ActionType::MergeModules:
@@ -639,6 +653,7 @@ bool FrontendOptions::doesActionProduceOutput(ActionType action) {
639653
case ActionType::DumpPCM:
640654
case ActionType::ScanDependencies:
641655
case ActionType::ScanClangDependencies:
656+
case ActionType::PrintFeature:
642657
return true;
643658

644659
case ActionType::NoneAction:
@@ -687,6 +702,7 @@ bool FrontendOptions::doesActionProduceTextualOutput(ActionType action) {
687702
case ActionType::ScanDependencies:
688703
case ActionType::ScanClangDependencies:
689704
case ActionType::PrintVersion:
705+
case ActionType::PrintFeature:
690706
return true;
691707
}
692708
llvm_unreachable("unhandled action");
@@ -714,6 +730,7 @@ bool FrontendOptions::doesActionGenerateSIL(ActionType action) {
714730
case ActionType::ScanDependencies:
715731
case ActionType::ScanClangDependencies:
716732
case ActionType::PrintVersion:
733+
case ActionType::PrintFeature:
717734
return false;
718735
case ActionType::EmitSILGen:
719736
case ActionType::EmitSIBGen:
@@ -762,6 +779,7 @@ bool FrontendOptions::doesActionGenerateIR(ActionType action) {
762779
case ActionType::ScanDependencies:
763780
case ActionType::ScanClangDependencies:
764781
case ActionType::PrintVersion:
782+
case ActionType::PrintFeature:
765783
return false;
766784
case ActionType::Immediate:
767785
case ActionType::REPL:

lib/FrontendTool/FrontendTool.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "swift/Basic/SourceManager.h"
4949
#include "swift/Basic/Statistic.h"
5050
#include "swift/Basic/UUID.h"
51+
#include "swift/Option/Options.h"
5152
#include "swift/Frontend/DiagnosticVerifier.h"
5253
#include "swift/Frontend/Frontend.h"
5354
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
@@ -1842,6 +1843,51 @@ static bool printSwiftVersion(const CompilerInvocation &Invocation) {
18421843
return false;
18431844
}
18441845

1846+
static void printSingleFrontendOpt(llvm::opt::OptTable &table, options::ID id,
1847+
llvm::raw_ostream &OS) {
1848+
if (table.getOption(id).hasFlag(options::FrontendOption)) {
1849+
auto name = StringRef(table.getOptionName(id));
1850+
if (!name.empty()) {
1851+
OS << " \"" << name << "\",\n";
1852+
}
1853+
}
1854+
}
1855+
1856+
static bool printSwiftFeature(CompilerInstance &instance) {
1857+
ASTContext &context = instance.getASTContext();
1858+
const CompilerInvocation &invocation = instance.getInvocation();
1859+
const FrontendOptions &opts = invocation.getFrontendOptions();
1860+
std::string path = opts.InputsAndOutputs.getSingleOutputFilename();
1861+
std::error_code EC;
1862+
llvm::raw_fd_ostream out(path, EC, llvm::sys::fs::F_None);
1863+
1864+
if (out.has_error() || EC) {
1865+
context.Diags.diagnose(SourceLoc(), diag::error_opening_output, path,
1866+
EC.message());
1867+
out.clear_error();
1868+
return true;
1869+
}
1870+
std::unique_ptr<llvm::opt::OptTable> table = createSwiftOptTable();
1871+
1872+
out << "{\n";
1873+
SWIFT_DEFER {
1874+
out << "}\n";
1875+
};
1876+
out << " \"SupportedArguments\": [\n";
1877+
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
1878+
HELPTEXT, METAVAR, VALUES) \
1879+
printSingleFrontendOpt(*table, swift::options::OPT_##ID, out);
1880+
#include "swift/Option/Options.inc"
1881+
#undef OPTION
1882+
out << " \"LastOption\"\n";
1883+
out << " ],\n";
1884+
out << " \"SupportedFeatures\": [\n";
1885+
// Print supported featur names here.
1886+
out << " \"LastFeature\"\n";
1887+
out << " ]\n";
1888+
return false;
1889+
}
1890+
18451891
static bool
18461892
withSemanticAnalysis(CompilerInstance &Instance, FrontendObserver *observer,
18471893
llvm::function_ref<bool(CompilerInstance &)> cont) {
@@ -1904,6 +1950,8 @@ static bool performAction(CompilerInstance &Instance,
19041950
return Context.hadError();
19051951
case FrontendOptions::ActionType::PrintVersion:
19061952
return printSwiftVersion(Instance.getInvocation());
1953+
case FrontendOptions::ActionType::PrintFeature:
1954+
return printSwiftFeature(Instance);
19071955
case FrontendOptions::ActionType::REPL:
19081956
llvm::report_fatal_error("Compiler-internal integrated REPL has been "
19091957
"removed; use the LLDB-enhanced REPL instead.");
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %target-swift-frontend -emit-supported-features %s | %FileCheck %s
2+
3+
// CHECK: "SupportedArguments"
4+
// CHECK: "emit-module"
5+
// CHECK: "LastOption"
6+
// CHECK: "SupportedFeatures"
7+
// CHECK: "LastFeature"

0 commit comments

Comments
 (0)