[Playgrounds] Add a new -playground-option flag to control which transforms to apply (#69355)

Generalize the existing `-playground-high-performance` flag into a set of options that control various aspects of the "playground transformation" in Sema.

This commit adds the first two of those controllable parts of the transform, matching what the existing flag already controls (scope entry/exit and function arguments), but in an extensible way. The intent is for this to be a scalable way to control a larger set of upcoming options.

So instead of a single flag, we represent the playground transform options as a set of well-defined choices, with a new `-playground-option` flag to individually enable or disable those options (when prefixed with "No", the corresponding option is instead disabled). Enabling an already-enabled option or disabling an already-disabled option is a no-op.

For compatibility, the existing `-playground-high-performance` flag causes "expensive" transforms to be disabled, as before. We can also leave it as a useful shorthand to include or exclude new options even in the future, based on their cost. There is a comment on the old function indicating that new code should use the more general form, but it remains for clients like LLDB until they can switch over.

The machinery for implementing the playground options is similar to how `Features.def` works, with a new `PlaygroundOptions.def` that defines the supported playground transform options.  Each playground definition specifies the name and description, as well as whether the option is enabled by default, and whether it's also enabled in the "high performance" case.

Adding a new option in the future only requires adding it to `PlaygroundOptions.def`, deciding whether it should be on or off by default, deciding whether it should also be on or off in `-playground-high-performance` mode, and checking for its presence from the appropriate places in `PlaygroundTransform.cpp`.

Note that this is intended to control the types of user-visible results that the invoker of the compiler wants, from an externally detectable standpoint. Other flags, such as whether or not to use the extended form of the callbacks, remain as experimental features, since those deal with the mechanics and not the desired observed behavior.

rdar://109911673
This commit is contained in:
Anders Bertelrud
2023-11-15 13:02:34 -08:00
committed by GitHub
parent bfcdfafee6
commit a363603c14
11 changed files with 273 additions and 25 deletions

View File

@@ -725,8 +725,26 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.PlaygroundTransform |= Args.hasArg(OPT_playground);
if (Args.hasArg(OPT_disable_playground_transform))
Opts.PlaygroundTransform = false;
Opts.PlaygroundHighPerformance |=
Args.hasArg(OPT_playground_high_performance);
if (Args.hasArg(OPT_playground_high_performance)) {
// Disable any playground options that are marked as not being enabled in
// high performance mode.
#define PLAYGROUND_OPTION(OptionName, Description, DefaultOn, HighPerfOn) \
if (!HighPerfOn) \
Opts.PlaygroundOptions.erase(PlaygroundOption::OptionName);
#include "swift/Basic/PlaygroundOptions.def"
}
for (const Arg *A : Args.filtered(OPT_playground_option)) {
// Enable the option (or disable if it has a "No" prefix). Any unknown
// options are ignored.
StringRef optionName = A->getValue();
const bool disableOption = optionName.consume_front("No");
if (auto option = getPlaygroundOption(optionName)) {
if (disableOption)
Opts.PlaygroundOptions.erase(*option);
else
Opts.PlaygroundOptions.insert(*option);
}
}
// This can be enabled independently of the playground transform.
Opts.PCMacro |= Args.hasArg(OPT_pc_macro);