This patch fixes two instances of the compiler embedded in LLDB
miscompiling code for expression evaluation, because of a combination of
the debugger's access to private types and resilience, which would cause
the generated code to access fields indirectly through resilience functions
that were never emitted.
rdar://137876089
The main change here is to associate a witness table with a `ProtocolConformance` instead of a `RootProtocolConformance`.
A `ProtocolConformance` is the base class and can be a `RootProtocolConformance` or a `SpecializedProtocolConformance`.
Motivated by need for protocol-based dynamic dispatch, which hasn't been possible in Embedded Swift due to a full ban on existentials. This lifts that restriction but only for class-bound existentials: Class-bound existentials are already (even in desktop Swift) much more lightweight than full existentials, as they don't need type metadata, their containers are typically 2 words only (reference + wtable pointer), don't incur copies (only retains+releases).
Included in this PR:
[x] Non-generic class-bound existentials, executable tests for those.
[x] Extension methods on protocols and using those from a class-bound existential.
[x] RuntimeEffects now differentiate between Existential and ExistentialClassBound.
[x] PerformanceDiagnostics don't flag ExistentialClassBound in Embedded Swift.
[x] WTables are generated in IRGen when needed.
Left for follow-up PRs:
[ ] Generic classes support
Those functions are effectively outlined functions with an alwaysinline
attribute. By removing their debug info and relying on the inliner to propagate
the call site location to the inlined instructions, we restore the "original"
locations as if the function had never been outlined.
This is technically relying on an implementation detail of the inliner, but it
seems to be the simplest way of addressing this issue.
The patch adds lowering of partial_apply instructions for coroutines.
This pattern seems to trigger a lot of type mismatch errors in IRGen, because
coroutine functions are not substituted in the same way as regular functions
(see the patch 07f03bd2 "Use pattern substitutions to consistently abstract
yields" for more details).
Other than that, lowering of partial_apply for coroutines is straightforward: we
generate another coroutine that captures arguments passed to the partial_apply
instructions. It calls the original coroutine for yields (first return) and
yields the resulting values. Then it calls the original function's continuation
for return or unwind, and forwards them to the caller as well.
After IRGen, LLVM's Coroutine pass transforms the generated coroutine (along with
all other coroutines) and eliminates llvm.coro.* intrinsics. LIT tests check
LLVM IR after this transformation.
Co-authored-by: Anton Korobeynikov <anton@korobeynikov.info>
Co-authored-by: Arnold Schwaighofer <aschwaighofer@apple.com>
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
At Onone, many types of functions (anything user written, compiler
generated setters and getters, etc), should be kept in the final
binary so they're accessible by the debugger.
rdar://126763340
We changed to `llvm.compiler.used` because of the behaviour of `gold`,
which refuses to coalesce sections that have different `SHF_GNU_RETAIN`
flags, which causes problems with metadata.
Originally I thought we were going to have to generate two sections
with distinct names and have the runtime look for both of them, but
it turns out that the runtime only wants to see sections that have
`SHF_GNU_RETAIN` in any case. It's really the reflection code that
is interested in being able to see non-retained sections. The upshot
is that we don't need to use `llvm.compiler.used`; it's just fine if
we have duplicate sections, as long as the reflection code looks for
them when it's inspecting an ELF image.
This also means we no longer need to pass `-z nostart-stop-gc` to the
linker if we're using `lld`.
rdar://123504095
When Swift imports C structs, it synthesizes an initializer that takes no arguments and zero-initializes the C struct.
When C++ interop is enabled, Clang treats all C structs as if they were C++ structs. This means that some of the C structs will get a default constructor implicitly generated by Clang. This implicit default constructor will not zero-initialize trivial fields of the struct.
This is a common source of confusion and subtle bugs for developers who try to enable C++ interop in existing projects that use C interop and rely on zero-initialization of C structs.
rdar://115909532
We don't currently support building resilient relative protocol witness tables.
One might want to build with relative witness tables but not need
resilient protocols. Allow for that scenario.
Add a test configuration to test library-evolution + fragile resilient
protocols + relative protocol witness tables.
Distributed protocol requirements don't have associated SILFunction,
let's introduce a more flexible way to define it that collects only
the information necessary for the function to become accessible.
Fix a bug in expandExternalSignatureTypes where it wasn't annotating a function call parameter type with sret when the result was being returned indirectly.
The bug was causing calls to ObjC methods that return their results indirectly to crash.
Additionally, fix the return type for C++ constructors computed in expandExternalSignatureTypes. Previously, the return type was always void even on targets that require constructors to return this (e.g., Apple arm64), which was causing C++ constructor thunks to be emitted needlessly.
Resolves rdar://121618707
Decls with a package access level are currently set to public SIL
linkages. This limits the ability to have more fine-grained control
and optimize around resilience and serialization.
This PR introduces a separate SIL linkage and FormalLinkage for
package decls, pipes them down to IRGen, and updates linkage checks
at call sites to include package linkage.
Resolves rdar://121409846
First, "can have an absence of Copyable" is a rather confusing notion,
so the query is flipped to "can be Copyable". Next, it's more robust to
ask if a conformance exists for the TypeDecl to answer that question,
rather than trying to replicate what happens within that conformance
lookup.
Also renames `TypeDecl::isEscapable` to match.