When an accessor macro adds a non-observing accessor to a property, it
subsumes the initializer. We had previously modeled this as removing
the initializer, but doing so means that the initializer could not be
used for type inference and was lost in the AST.
Explicitly mark the initializer as "subsumed" here, and be more
careful when querying the initializer to distinguish between "the
initializer that was written" and "the initializer that will execute"
in more places. This distinction already existed at the
pattern-binding level, but not at the variable-declaration level.
This is the proper fix for the circular reference issue described in
rdar://108565923 (test case in the prior commit).
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
Provide ASTWalker with a customization point to specify whether to
check macro arguments (which are type checked but never emitted), the
macro expansion (which is the result of applying the macro and is
actually emitted into the source), or both. Provide answers for the
~115 different ASTWalker visitors throughout the code base.
Fixes rdar://104042945, which concerns checking of effects in
macro arguments---which we shouldn't do.
Replace the use of bool and pointer returns for
`walkToXXXPre`/`walkToXXXPost`, and instead use
explicit actions such as `Action::Continue(E)`,
`Action::SkipChildren(E)`, and `Action::Stop()`.
There are also conditional variants, e.g
`Action::SkipChildrenIf`, `Action::VisitChildrenIf`,
and `Action::StopIf`.
There is still more work that can be done here, in
particular:
- SourceEntityWalker still needs to be migrated.
- Some uses of `return false` in pre-visitation
methods can likely now be replaced by
`Action::Stop`.
- We still use bool and pointer returns internally
within the ASTWalker traversal, which could likely
be improved.
But I'm leaving those as future work for now as
this patch is already large enough.
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.
We'll need this to get the right 'selfDC' when name lookup
finds a 'self' declaration in a capture list, eg
class C {
func bar() {}
func foo() {
_ = { [self] in bar() }
}
}
Like switch cases, a catch clause may now include a comma-
separated list of patterns. The body will be executed if any
one of those patterns is matched.
This patch replaces `CatchStmt` with `CaseStmt` as the children
of `DoCatchStmt` in the AST. This necessitates a number of changes
throughout the compiler, including:
- Parser & libsyntax support for the new syntax and AST structure
- Typechecking of multi-pattern catches, including those which
contain bindings.
- SILGen support
- Code completion updates
- Profiler updates
- Name lookup changes
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.
Change the various AST transforms to use prebuilt DeclName constants more heavily rather than an ad-hoc mix of Identifiers, string literals, std::strings, and StringRefs with questionable memory management.
This is an amalgam of simplifications to the way VarDecls are checked
and assigned interface types.
First, remove TypeCheckPattern's ability to assign the interface and
contextual types for a given var decl. Instead, replace it with the
notion of a "naming pattern". This is the pattern that semantically
binds a given VarDecl into scope, and whose type will be used to compute
the interface type. Note that not all VarDecls have a naming pattern
because they may not be canonical.
Second, remove VarDecl's separate contextual type member, and force the
contextual type to be computed the way it always was: by mapping the
interface type into the parent decl context.
Third, introduce a catch-all diagnostic to properly handle the change in
the way that circularity checking occurs. This is also motivated by
TypeCheckPattern not being principled about which parts of the AST it
chooses to invalidate, especially the parent pattern and naming patterns
for a given VarDecl. Once VarDecls are invalidated along with their
parent patterns, a large amount of this diagnostic churn can disappear.
Unfortunately, if this isn't here, we will fail to catch a number of
obviously circular cases and fail to emit a diagnostic.
Like the last commit, SourceFile is used a lot by Parse and Sema, but
less so by the ClangImporter and (de)Serialization. Split it out to
cut down on recompilation times when something changes.
This commit does /not/ split the implementation of SourceFile out of
Module.cpp, which is where most of it lives. That might also be a
reasonable change, but the reason I was reluctant to is because a
number of SourceFile members correspond to the entry points in
ModuleDecl. Someone else can pick this up later if they decide it's a
good idea.
No functionality change.
Most of AST, Parse, and Sema deal with FileUnits regularly, but SIL
and IRGen certainly don't. Split FileUnit out into its own header to
cut down on recompilation times when something changes.
No functionality change.
Accessors logically belong to their storage and can be synthesized
on the fly, so removing them from the members list eliminates one
source of mutability (but doesn't eliminate it; there are also
witnesses for derived conformances, and implicit constructors).
Since a few ASTWalker implementations break in non-trivial ways when
the traversal is changed to visit accessors as children of the storage
rather than peers, I hacked up the ASTWalker to optionally preserve
the old traversal order for now. This is ugly and needs to be cleaned up,
but I want to avoid breaking _too_ much with this commit.
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
Right now we use TupleShuffleExpr for two completely different things:
- Tuple conversions, where elements can be re-ordered and labels can be
introduced/eliminated
- Complex argument lists, involving default arguments or varargs
The first case does not allow default arguments or varargs, and the
second case does not allow re-ordering or introduction/elimination
of labels. Furthermore, the first case has a representation limitation
that prevents us from expressing tuple conversions that change the
type of tuple elements.
For all these reasons, it is better if we use two separate Expr kinds
for these purposes. For now, just make an identical copy of
TupleShuffleExpr and call it ArgumentShuffleExpr. In CSApply, use
ArgumentShuffleExpr when forming the arguments to a call, and keep
using TupleShuffleExpr for tuple conversions. Each usage of
TupleShuffleExpr has been audited to see if it should instead look at
ArgumentShuffleExpr.
In sequent commits I plan on redesigning TupleShuffleExpr to correctly
represent all tuple conversions without any unnecessary baggage.
Longer term, we actually want to change the representation of CallExpr
to directly store an argument list; then instead of a single child
expression that must be a ParenExpr, TupleExpr or ArgumentShuffleExpr,
all CallExprs will have a uniform representation and ArgumentShuffleExpr
will go away altogether. This should reduce memory usage and radically
simplify parts of SILGen.
It is possible for the SIL optimizers, IRGen, etc. to request information
from the AST that only the type checker can provide, but the type checker
is typically torn down after the “type checking” phase. This can lead to
various crashes late in the compilation cycle.
Keep the type checker instance around as long as the ASTContext is alive
or until someone asks for it to be destroyed.
Fixes SR-285 / rdar://problem/23677338.
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>.
Previously, some PBDs weren't being marked implicit even though the associated vars were implicit. PatternBindingDecl::createImplicit will be even nicer when we start parsing the location of the equals token.
Several different places in the codebase synthesize IntegerLiteralExprs from computed unsigned variables; each one requires several lines of code and does things slightly differently. Write one central helper method to handle this.
Added handling of `defer` statements in the playground transform.
Tests will be added in a follow-on commit.
Patch by Roman Levenstein!
This addresses SR-5641/<rdar://problem/33764082>.
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
Also, begin to pass around base types instead of raw InOutType types. Ideally, only Sema needs to deal with them, but this means that a bunch of callers need to unwrap any inouts that might still be lying around before forming these types.
Multiple parts of the compiler were slicing, dicing, or just dropping these flags. Because I intend to use them for the new function type representation, I need them to be preserved all across the compiler. As a first pass, this stubs in what will eventually be structural rules as asserts and tracks down all callers of consequence to conform to the new invariants.
This is temporary.
In anticipation of future attributes, and perhaps the ability to
declare lvalues with specifiers other than 'let' and 'var', expand
the "isLet" bit into a more general "specifier" field.
With the introduction of special decl names, `Identifier getName()` on
`ValueDecl` will be removed and pushed down to nominal declarations
whose name is guaranteed not to be special. Prepare for this by calling
to `DeclBaseName getBaseName()` instead where appropriate.
Replace `NameOfType foo = dyn_cast<NameOfType>(bar)` with DRY version `auto foo = dyn_cast<NameOfType>(bar)`.
The DRY auto version is by far the dominant form already used in the repo, so this PR merely brings the exceptional cases (redundant repetition form) in line with the dominant form (auto form).
See the [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es11-use-auto-to-avoid-redundant-repetition-of-type-names) for a general discussion on why to use `auto` to avoid redundant repetition of type names.