Reformatting everything now that we have `llvm` namespaces. I've
separated this from the main commit to help manage merge-conflicts and
for making it a bit easier to read the mega-patch.
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".
I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
This patch replaces the stateful generation of SILScope information in
SILGenFunction with data derived from the ASTScope hierarchy, which should be
100% in sync with the scopes needed for local variables. The goal is to
eliminate the surprising effects that the stack of cleanup operations can have
on the current state of SILBuilder leading to a fully deterministic (in the
sense of: predictible by a human) association of SILDebugScopes with
SILInstructions. The patch also eliminates the need to many workarounds. There
are still some accomodations for several Sema transformation passes such as
ResultBuilders, which don't correctly update the source locations when moving
around nodes. If these were implemented as macros, this problem would disappear.
This necessary rewrite of the macro scope handling included in this patch also
adds proper support nested macro expansions.
This fixes
rdar://88274783
and either fixes or at least partially addresses the following:
rdar://89252827
rdar://105186946
rdar://105757810
rdar://105997826
rdar://105102288
As I've been iterating on this work, I've been gradually mulling these
over, and I think this is the way to go for now. These should make it
a lot less cumbersome to write these kinds of traversals correctly.
The intent is to the sunset the existing expanded-components stuff
after I do a similar pass for function parameters.
More missing infrastructure. In this case, it's really *existing*
missing infrastructure, though; we should have been imploding tuples
this way all along, given that we're doing it in the first place.
I don't like that we're doing all these extra tuple copies. I'm not
sure yet if they're just coming out of SILGen and eliminated immediately
after in practice; maybe so. Still, it should be obvious that they're
unnecessary.
This is all relatively nicely abstracted, which is not to say that
it didn't take an awful lot of plumbing to get it to work. The basic
problem here is inherent: we need to do component-specific setup and
teardown, and unfortunately in the current representation we have to
do that with separate loops and without any dominance relationships.
(This is the same thing preventing us from doing borrows in the
general case.) The result is that the general case of result emission
is to emit every element of the expansion into a temporary tuple
(requiring a pack loop before the call to initialize the pack), then
process those elements in the body of a second pack loop after the
call. And that's terrible enough that we really have to do the work
to try to avoid it, which makes all the APIs more complicated.
Anyway, most of the way through the basic plumbing for variadic
generics now. Next is reabstraction, I think, which I hope will
mostly mean fixing bugs in the infrastructure I've already written.
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`
The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.
rdar://102362022
We had two notions of canonical types, one is the structural property
where it doesn't contain sugared types, the other one where it does
not contain reducible type parameters with respect to a generic
signature.
Rename the second one to a 'reduced type'.
This for some time has been crashing in IRGen in non-asserts builds and hitting
assertions in asserts builds. I think we were missing test coverage here and
that is why this basic-ish thing has been broken.
Basically at a high level, the actual expected ABI here is that the NSError is
marked non-nullable which is different from the expected ABI.
rdar://92755102
when two objc async functions are composed with each other,
i.e., f(g()), then the clean-ups for g() would get emitted
at an unexpected time, namely, during the suspension for
the call to f(). This means that using a clean-up to emit
the executor-hop breadcrumb was incorrect. The hop could
appear between a get_async continuation and its matching
await_continuation, which is an unsupported nested suspension.
This commit fixes that by removing the use of the breadcrumb
clean-up in favor of providing that breadcrumb directly to
the result plan, so that it may be emitted later on when the
result plan sees fit.
Fixes rdar://91502776
- Add a `[reflection]` bit to `alloc_box` instructions, to indicate that a box
should be allocated with reflection metadata attached.
- Add a `@captures_generics` attribute to SILLayouts, to indicate a type layout
that captures the generic arguments it's substituted with, meaning it can
recreate the generic environment without additional ABI-level arguments, like
a generic partial application can.
Previously, the AbstractionPattern that was used for the value
"returned" (i.e. via a completion handler) from ObjC mostly (but not
quite always) was "type".
The generated completion handler correctly (because this is required in
order to call _resumeUnsafeContinuation) reabstracted the block (e.g.
from @convention(block) to @substituted <T> () -> @out T for <()>). The
callee of the ObjC function, however, loaded the function from the block
as if it were not reabstracted (e.g. () -> ()).
On most platforms, that happened to work. On arm64e, that difference in
types caused in a difference in pointer signing, resulting in a failure
at runtime.
rdar://85526879
rdar://85526916
Clients can explicitly ask for the opened existential type on the archetype's generic environment,
or use `getExistentialType` to obtain a specific archetype's upper bounds.
Because AllocBoxToStack is not able to transform every alloc_box into an
alloc_stack, it's necessary to add begin_borrow [lexical] to every
alloc_box in order to provide lexical scopes for those alloc_boxes which
will not be transformed into alloc_stacks.
Use APIs for creating terminator results that handle forwarding
ownership consistently.
Add ManagedValue::forForwardedRValue(SILValue) to handle cleanups
consistently based on ownership forwarding.
Add SILGenBuilder::createForwardedTermResult(SILType type) for
creating termator results with the correct ownership and cleanups.
Add SILGenBuilder::createTermResult(SILType type, ValueOwnershipKind
ownership) that handles cleanup based on terminator result ownership.
Add SILGenBuilder::createOptionalSomeResult(SwitchEnumInst) so a lot
of code doesn't need to deal with unwrapping Optional types,
terminator results, and ownership rules.
Replace the existing "phi" APIs with a single
SILGenBuilder::createPhi(SILType, ValueOwnershipKind) that handles
cleanup based on phi ownership.
Phis and terminator results are fundamentally different and need to be handled differently everywhere. Remove the confusion where terminator results were generated with a "phi argument" API.
Previously, SILGen assumed that a foreign function could either have a
foreign async convention or a foreign error convention, but if it had
both, the error would be subsumed into the completion. That resulted in
failures to emit code for async calls of functions like
```
- (BOOL)minimalWithError:(NSError* _Nullable*)error
completionHandler:(void (^ _Nonnull)(void))completionHandler;
```
Here, SILGen gains the ability to emit such functions. To enable that,
a few changes were required when both conventions are present:
- a separate argument for each convention is used
- the ResultPlan is a ForeignErrorResultPlan nesting a
ForeignAsyncResultPlan
- the continuation is always of the form UnsafeContinuation<_, Error>
regardless of whether the completion handler takes an error
- the foreign error block fills the continuation with the error that was
passed by reference out of the ObjC method call
- the foreign error block branches to the block containing the await
instruction
rdar://80704984
Previously, AbstractionPattern::getOpaque() was used for async
continuations. That was problematic for functions like
```objc
- (void)performVoid2VoidWithCompletion:(void (^ _Nonnull)(void (^ _Nonnull)(void)))completion;
```
whose completion takes a closure. Doing so resulted in attempting to
build a block to func thunk where one of the functions had an out
parameter.
Instead, use the AbstractionPattern(ty).
rdar://79383990
Address a FIXME where lowered types rather than formal types were used
when converting from objc to native types which resulted in a failure to
convert block types.
This is kind of complicated, because an enum can be trivial for one case and not trivial for another case. We need to check at which parts of the function we can prove that the enum does (or could) have a trivial case. In such a branch, it's not required in SIL to destroy the enum location.
Also, document the rules and requirements for enum memory locations in SIL.rst.
rdar://73770085
Plumb generic signatures through the codegen for invoking foreign APIs as async, so that we
correctly handle APIs declared on ObjC lightweight generic classes. rdar://74361267
The goal of doing this is to reduce the amount of boilerplate and repeated code w.r.t. Continuation. Having just added `resume()` in four places, I got the sense that there was a lot of common code that was being duplicated. I removed the Throwing variants of these types (they can be expressed as Continuation<T, E:Error> instead of ThrowingContinuation<E>) and I broke out a significant amount of common code between CheckedContinuation and UnsafeContinuation into an implementation-only protocol to avoid repeating it. D.R.Y.
This change resolves rdar://74154769.
Immediately before invoking the ObjC API, get the current continuation, capture it into a block to
pass as the completion handler, and then await the continuation, whose resume/error successors
serve as the semantic return/throw result of the call. This should complete the caller-side part
of SILGen; the completion handler block implementation is however still only a stub.
Allow SILGen to not crash when invoking foreign async methods by emitting
`undef` for the completion callback going into the call, and for the
results that would be channeled back through awaiting the continuation.