[Frontend] Add -print-supported-features option

This is a replacement for `-emit-supported-features` that prints
all of the upcoming/experimental features supported by the compiler
with some additional meta information in JSON format to stdout.
This commit is contained in:
Pavel Yaskevich
2025-04-14 16:57:11 -07:00
parent 7ce06dde2c
commit 55bd906906
9 changed files with 153 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
//===--- SupportedFeatures.h - Supported Features Output --------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file provides a high-level API for supported features info
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SUPPORTEDFEATURES_H
#define SWIFT_SUPPORTEDFEATURES_H
#include "swift/Basic/LLVM.h"
namespace swift {
namespace features {
void printSupportedFeatures(llvm::raw_ostream &out);
} // namespace features
} // namespace swift
#endif

View File

@@ -314,6 +314,10 @@ public:
/// exit.
bool PrintTargetInfo = false;
/// Indicates that the frontend should print the supported features and then
/// exit.
bool PrintSupportedFeatures = false;
/// See the \ref SILOptions.EmitVerboseSIL flag.
bool EmitVerboseSIL = false;

View File

@@ -1534,6 +1534,10 @@ def print_target_info : Flag<["-"], "print-target-info">,
Flags<[FrontendOption]>,
HelpText<"Print target information for the given target <triple>, such as x86_64-apple-macos10.9">, MetaVarName<"<triple>">;
def print_supported_features : Flag<["-"], "print-supported-features">,
Flags<[FrontendOption]>,
HelpText<"Print information about features supported by the compiler">;
def target_cpu : Separate<["-"], "target-cpu">, Flags<[FrontendOption, ModuleInterfaceOption]>,
HelpText<"Generate code for a particular CPU variant">;

View File

@@ -75,6 +75,7 @@ add_swift_host_library(swiftBasic STATIC
StableHasher.cpp
Statistic.cpp
StringExtras.cpp
SupportedFeatures.cpp
TargetInfo.cpp
TaskQueue.cpp
ThreadSafeRefCounted.cpp

View File

@@ -0,0 +1,74 @@
//===--- SupportedFeatures.cpp - Supported features printing --------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#include <array>
#include <vector>
#include "swift/Basic/Feature.h"
#include "swift/Frontend/Frontend.h"
#include "llvm/Support/raw_ostream.h"
using namespace swift;
namespace swift {
namespace features {
/// Print information about what features upcoming/experimental are
/// supported by the compiler.
/// The information includes whether a feature is adoptable and for
/// upcoming features - what is the first mode it's introduced.
void printSupportedFeatures(llvm::raw_ostream &out) {
std::array upcoming{
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description)
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) Feature::FeatureName,
#include "swift/Basic/Features.def"
};
std::vector<swift::Feature> experimental{{
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description)
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) Feature::FeatureName,
#include "swift/Basic/Features.def"
}};
// Include only experimental features that are available in production.
llvm::erase_if(experimental, [](auto &feature) {
return feature.isAvailableInProduction();
});
out << "{\n";
auto printFeature = [&out](const Feature &feature) {
out << " ";
out << "{ \"name\": \"" << feature.getName() << "\"";
if (feature.isAdoptable()) {
out << ", \"migratable\": true";
}
if (auto version = feature.getLanguageVersion()) {
out << ", \"enabled_in\": " << *version;
}
out << " }";
};
out << " \"features\": {\n";
out << " \"upcoming\": [\n";
llvm::interleave(upcoming, printFeature, [&out] { out << ",\n"; });
out << "\n ],\n";
out << " \"experimental\": [\n";
llvm::interleave(experimental, printFeature, [&out] { out << ",\n"; });
out << "\n ]\n";
out << " }\n";
out << "}\n";
}
} // end namespace features
} // end namespace swift

View File

@@ -2049,6 +2049,28 @@ bool Driver::handleImmediateArgs(const ArgList &Args, const ToolChain &TC) {
return false;
}
if (Args.hasArg(options::OPT_print_supported_features)) {
SmallVector<const char *, 5> commandLine;
commandLine.push_back("-frontend");
commandLine.push_back("-print-supported-features");
std::string executable = getSwiftProgramPath();
// FIXME(https://github.com/apple/swift/issues/54554): This bypasses
// mechanisms like -v and -###.
sys::TaskQueue queue;
queue.addTask(executable.c_str(), commandLine);
queue.execute(nullptr,
[](sys::ProcessId PID, int returnCode, StringRef output,
StringRef errors, sys::TaskProcessInformation ProcInfo,
void *unused) -> sys::TaskFinishedResponse {
llvm::outs() << output;
llvm::errs() << errors;
return sys::TaskFinishedResponse::ContinueExecution;
});
return false;
}
return true;
}

View File

@@ -206,6 +206,10 @@ bool ArgsToFrontendOptionsConverter::convert(
Opts.PrintTargetInfo = true;
}
if (Args.hasArg(OPT_print_supported_features)) {
Opts.PrintSupportedFeatures = true;
}
if (const Arg *A = Args.getLastArg(OPT_verify_generic_signatures)) {
Opts.VerifyGenericSignaturesInModule = A->getValue();
}

View File

@@ -46,6 +46,7 @@
#include "swift/Basic/PrettyStackTrace.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Basic/Statistic.h"
#include "swift/Basic/SupportedFeatures.h"
#include "swift/Basic/TargetInfo.h"
#include "swift/Basic/UUID.h"
#include "swift/Basic/Version.h"
@@ -2063,6 +2064,11 @@ int swift::performFrontend(ArrayRef<const char *> Args,
return finishDiagProcessing(0, /*verifierEnabled*/ false);
}
if (Invocation.getFrontendOptions().PrintSupportedFeatures) {
swift::features::printSupportedFeatures(llvm::outs());
return finishDiagProcessing(0, /*verifierEnabled*/ false);
}
if (Invocation.getFrontendOptions().RequestedAction ==
FrontendOptions::ActionType::NoneAction) {
Instance->getDiags().diagnose(SourceLoc(),

View File

@@ -0,0 +1,10 @@
// RUN: %target-swift-frontend -print-supported-features | %FileCheck %s
// CHECK: "features": {
// CHECK-NEXT: "upcoming": [
// CHECK: { "name": "{{.*}}"{{, "migratable": true}}, "enabled_in": {{[0-9]+}} }
// CHECK: ],
// CHECK-NEXT: "experimental": [
// CHECK: { "name": "{{.*}}"{{, "migratable": true}} }
// CHECK: ]
// CHECK: }