The backtracing code will warn you if you attempt to forcibly enable
backtracing for a privileged executable. This is apparently upsetting
the Driver/filelists.swift test.
Since we want to force it on for tests, so that we will definitely get
backtraces, add an option to suppress warning messages, and turn that
on for tests as well.
rdar://144497613
The crash was caused by attempting to add logging expressions that capture generic variables while using the outer func decl context that was not the generic decl context of the inner (generic) func.
The fix "pushes" the current func decl context while instrumenting the body. Rather than always using the top-level func decl context for all nested func bodies.
Defines the %target-playground-build-run-swift macro in the local lit config for PlaygroundTransform which contains all the boilerplate code used by most PlaygroundTransform tests:
* Build a PlaygroundSupport module
* Build the test source into an executable, linking PlaygroundSupport
* Codesign and run the executable
When a decl that has properties with accessors (`get`, `set`, `willSet`, `didSet`, `subscript()`, etc) is nested inside another type, those accessor implementations aren't playground-transformed.
The reason is that the playground transform uses an `ASTWalker` to get to the top-level structure, but then once it’s inside a type, it does directly nested `transformDecl()` calls. And that inner check is missing a case for accessors.
This change adds an else-clause that checks if the declaration is a `AbstractVarDecl`, and if so, calls `transformDecl()` on each accessor.
It's unfortunate that the playground transform reaches decls in two different ways (using an `ASTWalker` to get to the top-level decls but then using directly nested calls below). That issue seems to be worth resolving at some point (perhaps by using the `ASTWalker` for the whole traversal?)... but that would be a larger change requiring more thought, and so the missing results being fixed here are worth addressing with a safer short-term fix.
rdar://139656464
The problem here is when wrapping a type that has constructors and destructors inside another type.
The reason is that the playground transform uses an `ASTWalker` to get to the top-level structure, but then once it’s inside a type, it does directly nested transformDecl() calls. And that inner check was for too narrow of a type.
The problem in this case was that the `dyn_cast<FuncDecl>(D)` was too narrow and didn’t include constructors/destructors. We want `dyn_cast<AbstractFunctionDecl>(D)`.
We should probably resolve this duality (using an `ASTWalker` to get to the top-level decls but then using directly nested calls below) at some point, but that’s a larger change, and so the specific problem covered by this commit is worth addressing with this safer short-term fix.
Changes:
- change a `dyn_cast<FuncDecl>` to a `dyn_cast<AbstractFunctionDecl>` in PlaygroundTransform.cpp
- add a unit test nested init and deinit (this test also tests the unnested case)
rdar://137316110
When ImplicitOpenExistentials was enabled (default in Swift language mode 6) the Instrumenter would crash the compiler when building logger calls. This was due to an incorrect assumption that the newly created apply expr wouldn't change type when type-checked. However, the type checker is free to change the kind of expression and did so in circumstances where the call expr was wrapped in an open existential expr.
Find all the usages of `--enable-experimental-feature` or
`--enable-upcoming-feature` in the tests and replace some of the
`REQUIRES: asserts` to use `REQUIRES: swift-feature-Foo` instead, which
should correctly apply to depending on the asserts/noasserts mode of the
toolchain for each feature.
Remove some comments that talked about enabling asserts since they don't
apply anymore (but I might had miss some).
All this was done with an automated script, so some formatting weirdness
might happen, but I hope I fixed most of those.
There might be some tests that were `REQUIRES: asserts` that might run
in `noasserts` toolchains now. This will normally be because their
feature went from experimental to upcoming/base and the tests were not
updated.
With Swift 6 the print()/debugPrint() function decl is a sub expression of a function conversion expression.
Added tests for print() capture with -swift-version 6.
rdar://136858280
Skip playground transform for functions that have skipped bodies. This can happen when passing `-emit-module` and `-experimental-skip-non-inlinable-function-bodies-without-types` and also enabling the playground transform. This causes the type to be `nullptr`. The fix is for the playground transform to check `AbstractFunctionDecl::isBodySkipped()`.
rdar://119258854
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
* Add experimental feature `PlaygroundExtendedCallbacks` which passes more information in `-playground` callbacks
Adds the experimental feature `PlaygroundExtendedCallbacks` which (when `-playground` is also passed) causes the playground transform to use alternate forms of the result-value, scope-entry, and scope-exit callbacks that include the module name and file path of the source file.
The previous callbacks included integers for the module number and file number, but this was cumbersome to use because it required the caller to create source symbols with magical names formed from the module name and file path that the playground transform knew how to look up.
The extended callbacks in the experimental feature instead pass these strings as string literals. This is an experimental feature because of the need to measure the performance impact, and because of the need to provide an option to control which set of callbacks to use so that existing clients of the playground transform can opt into it when ready. It's also likely that we'll want to pass more information in the extended callbacks, such as an indication of the kind of result is being logged (e.g. a loop iteration variable vs a return statement vs a variable assignment). So this should be considered the first of a series of experimental improvements that will then be pitched as an actual, non-experimental v2.0 of the playground transform callback API. Because of the nature of how the playground transform is used, it's much easier to iterate on the functionality in the form of an experimental feature rather than using only desktop debug builds of the Swift compiler.
Changes:
- define a new experimental feature called `PlaygroundExtendedCallbacks`
- modify the playground transform step in sema to pass the module name and file name literals when the experimental feature is set
- add a unit test for the extended callbacks
There is no change in behaviour when `PlaygroundExtendedCallbacks` is not enabled.
rdar://109911742
Co-authored-by: Brent Shank <bshank@apple.com>
Add logging of function and closure parameter values when the playground transform is enabled and its "high-performance" mode is off.
MOTIVATION
The goal of the optional "playground transform" step in Sema is to instrument the code by inserting calls to `__builtin_log()` and similar log functions, in order to record the execution of the compiled code. Some IDEs (such as Xcode) enable this transform by passing -playground and provide implementations of the logger functions that record information that can then be shown in the IDE.
The playground transform currently logs variable assignments and return statements, but it doesn't log the input parameters received by functions and closures. Knowing these values can be very useful in order to understand the behaviour of functions and closures.
CHANGES
- add a `ParameterList` parameter to `InstrumenterSupport::transformBraceStmt()`
- this is an optional parameter list that, if given, specifies the parameters that should be logged at the start of the brace statement
- this has to be passed into the function because it comes from the owner of the BraceStmt
- adjust `PlaygroundTransform.cpp` to make use of this list
- the transform will insert calls to `__builtin_log()` for each of the parameters, in order
- adjust `PCMacro.cpp` to accept the parameter, though this instrumenter doesn't currently make use of the new information
- add two new unit tests (one for functions and one for closures)
- adjust four existing unit tests to account for the new log calls
REMARKS
- this is currently guarded by the existing "high performance" option (parameter logging is omitted in that case)
rdar://104974072
Async-let pattern-binding-decls can't be logged since they haven't been
await'd yet. This patch fixes it so the playground transform doesn't try
to log the async-let.
In debug configurations, fatal error messages include file & line number information. This update presents this information in a format matching the diagnostic conventions used by the compiler, which can be a slight productivity boost.
Code compiled with optimizations enabled (which is most production code) does not output this information, so it isn’t affected by this change.
Original format:
Fatal error: A suffusion of yellow: file calc.swift, line 5
New format:
calc.swift:5: Fatal error: A suffusion of yellow
Resolves rdar://68484891
The `-force-single-frontend-invocation` flag predates WMO and is now an
alias for `-whole-module-optimization`. We should use the latter and let
the former fade into history.
When a force-value expression (!) is encountered while logging
variables, retain the force-value expression rather than dropping it.
This allows logging involving implicitly unwrapped optionals.
Fixes rdar://problem/56098581.
This change PCMacro and PlaygroundTransform to return an a moduleID and
fileID in addition to the source location information. The Frontend has
been changed to run PCMacro and PlaygroundTransform on all input files
instead of the main file only.
The tests have been updated to conform to these changes with an addition
of module and file ID specific tests. The Playgrounds related tests were
adjusted to make a module out of the stub interface files since those
files should not have PCMacro and PlaygroundTransform applied to them.
rdar://problem/50821146
Allow the use of declarations whose names start with $ in all
modes. However, normal code cannot define new entities with names that
start with $: only the implementation can do that, e.g., for property
delegates.
In https://github.com/apple/swift/pull/23578, @jrose-apple gave some
comments on correctness of argument concatenation in regards to not.py.
The PR merged before I was able to address those changes.
Currently, the playground transform requires the use of dollar-identifiers as the functions are prefixed with "$builtin".
This commit removes that requirement by replacing "$builtin" with "__builtin".
This aligns with the PC macro.
This addresses <rdar://problem/36031860>.
This converts the instances of the pattern for which we have a proper
substitution in lit. This will make it easier to replace it
appropriately with Windows equivalents.
Since both in-tree AST transforms (playground and program counter) add
new ApplyExprs (and literals that turn into ApplyExprs), we need to
recheck nested function bodies as well as top-level ones.
rdar://problem/28784059
Based off the PlaygroundTransform, this new ASTWalker leaves calls to __builtin_pc_before and __builtin_pc_after before and after a user would expect a program counter to enter a range of source code.
The fix for missing logging for += accidentally made us log ALL functions that
return (), not just the ones that happen to touch inout parameters. That's not
really desirable, and resulted from a missing testcase.
This fixes the problem and adds a testcase.
<rdar://problem/27995558>