A witness table instantiation function can end up referring to
conditional requirements to, e.g., fill in base witness tables. Store
the conditional requirements first, and also bind the witness tables
for conditional requirements within the local scope so they can be
used directly. Fixes SR-6478.
When emitting a witness table accessor (e.g., an associated type metadata
or associated type conformance accessor) for a conditional conformance,
bind the conditional requirements so we can refer to them within that
accessor. Witness methods get this behavior already through the SelfWitnessTable parameter, but everything the witness table needs it.
Fixes most of SR-6478.
Rather than storing contextual types in the type witnesses and associated
conformances of NormalProtocolConformance, store only interface types.
@huonw did most of the work here, and @DougGregor patched things up to
complete the change.
This commit is mostly refactoring.
*) Introduce a new OptimizationMode enum and use that in SILOptions and IRGenOptions
*) Allow the optimization mode also be specified for specific SILFunctions. This is not used in this commit yet and thus still a NFC.
Also, fixes a minor bug: we didn’t run mandatory IRGen passes for functions with @_semantics("optimize.sil.never")
When calling an accessor, one has to pull the witness tables for each
conditional conformance requirement into a(n appropriately ordered) buffer that
is passed to the accessor. This is simple enough, if the appropriate
specialization of the relevant conformances are known, which the compiler didn't
track deep enough until now.
Conditional requirements shouldn't appear in witness_method's (IR) signature,
since they differ from conformance to conformance. PolymorphicConvention just
needs to consider these fulfilled by the self witness table, since they
can/should be pulled out of there.
This requires the witness table accessor function to gain two new parameters: a
pointer to an array of witness tables and their count. These are then passed down
to the instantiation function which reads them out of the array and writes them
into the newly-allocated witness table.
We use the count to assert that the number of conditional witness tables passed
in is what the protocol conformance expects, which is especially useful while
the feature is still experimental: it is a compiler/runtime bug if an incorrect
number is passed.
A concrete conformance may involve conditional conformances, which are witness
tables that we can access from the original conformance's one. We need to track
metadata and be able to follow it in a metadata path.
Pointers to the witness tables of any conditional conformances are placed into
private data, closest to the base pointer, i.e. wtable_ptr[-1] will be the
first (if any) conditional conformance witness table. These always need to be
provided by the context, and copied in when the witness table is instantiated,
making reserving space easy: increment the size of the private data section.
Finally, remove the parent type metadata argument from type
constructors.
Now that type constructors don't take a parent metadata pointer,
we can hit some asserts concerning type constructors that do not
have any parameters. This happens when you define a concrete type
in a fully-constrained extension of a generic type.
A more efficient ABI would use concrete type metadata for these
cases, but that would be a bigger change that we can do later, so
for now just relax these assertions.
This resolves a runtime crasher since a circular metadata case is
no longer circular. I renamed the crasher to reference the more
specific radar since the more general issue of circular metadata
is still unresolved.
This change makes it so that type metadata stores arguments
from each nesting depth. This means that parent metadata is
no longer needed to fulfill generic arguments, but we still
store a parent pointer in metadata and pass it to type
constructor functions at this point.
Again, let's just assert that we're emitting a reference
to a witness table for the exact conformance provided.
The inherited conformance case would not have handled
indirect refinement, where R refines Q refines P, and
we're asked to emit a witness table reference for P given
a conformance to R.
The SIL witness_method instruction takes a protocol method and a
protocol conformance. IRGen lowers this as a load of a function
pointer from a fixed offset in the witness table for the
conformance.
IRGen also handled the case where the conformance is to a
protocol that refines the protocol containing the requirement,
by calling ProtocolConformanceRef::getInherited() to map the
conformance stored in the instruction to the correct conformance
for the protocol requirement being called.
It appears that this possibilty is not exercised through our
test suite, and if this does come up it is better to fix
SILGen and the optimizer to construct witness_method calls
using exact conformances only instead.
Furthermore, ProtocolConformanceRef::getInherited() only handles
a single level of refinement. So for example, if a protocol R
refines Q which refines R, we would crash when lowering a
witness_method instruction that calls P.foo() with a conformance
to R.
Therefore, code that emits witness_method instructions with a
conformance to a protocol that doesn't match the requirement was
likely going to do the wrong thing in this case anyway. Moving
the assertion earlier in the pipeline will help shake out these
cases.
- Always include an array of requirement descriptors in the protocol
descriptor. For now, this doesn't contain anything except a general
requirement kind and an optional default implementation, but eventually
this can be augmented with type / name metadata. This array is always
emitted as constant.
- Guarantee the value of the extent fields in a protocol descriptor and
slightly tweak their meaning.
- Move the private-data field out of line in a generic witness table
descriptor so that the main descriptor can be emitted as constant.
- Rely on IRGen's notion of the witness-table layout instead of assuming
that SILWitnessTable and SILDefaultWitnessTable match the actual
physical layout.
This version of the patch uses a hack in which we assign internal rather
than private linkage to certain symbols in order to work around a Darwin
linker bug.
Similarly to Clang, the flag enables coverage instrumentation, and links
`libLLVMFuzzer.a` to the produced binary.
Additionally, this change affects the driver logic, and enables the
concurrent usage of multiple sanitizers.
To make this stick, I've disallowed direct use of that overload of
CreateCall. I've left the Constant overloads available, but eventually
we might want to consider fixing those, too, just to get all of this
code out of the business of manually remembering to pass around
attributes and calling conventions.
The test changes reflect the fact that we weren't really setting
attributes consistently at all, in this case on value witnesses.
The goals here are four-fold:
- provide cleaner internal abstractions
- avoid IR bloat from extra bitcasts
- avoid recomputing function-type lowering information
- allow more information to be propagated from the function
access site (e.g. class_method) to the call site
Use this framework immediately for class and protocol methods.
Use the KeyPath implementation's new support for instantiating and dealing with captures to lower the generic context required to dispatch computed accessors with dependent generics.
forwarding thunks
We omit passing some metatype parameters if they can be reconstructed from
regular arguments. However, the partial apply forwarder so far did not
reconstructing them from such arguments.
SR-4854
rdar://32134723
This means both not crashing when we deserialize the protocol but
also emitting correct offsets for dynamic dispatch through the
protocol's witness table.
Also fix a bug with vtable and witness table slots for
materializeForSet accessors for properties that can't be
imported. Because materializeForSet doesn't have the type of the
property in its signature, it was taking a different failure path from
everything else, and that failure path didn't properly set the name or
flags for the missing member.
Finishes rdar://problem/31878396
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.
Enums with the ns_error_domain attribute represent codes for NSError,
which means Swift developers will expect to interact with them in
terms of Error. SE-0112 improved bridging for these enums to generate
a struct with the following form:
struct MyError: Error {
@objc enum Code: RawRepresentable {
case outOfMemory
case fileNotFound
}
var userInfo: [NSObject: AnyObject] { get }
static var outOfMemory: Code { get }
static var fileNotFound: Code { get }
}
where MyError.Code corresponds to the original MyError enum defined in
Objective-C. Until recently, both the enum and the synthesized struct
were marked as having the original enum as their "Clang node", but
that leads to problems: the struct isn't really ObjC-compatible, and
the two decls have the same USR. (The latter had already been worked
around.)
This commit changes the struct to be merely considered a synthesized
"external definition", with no associated Clang node. This meant
auditing everywhere that's looking for a Clang node and seeing which
ones applied to external definitions in general.
There is one regression in quality here: the generated struct is no
longer printed as part of the Swift interface for a header file, since
it's not actually a decl with a corresponding Clang node. The previous
change to AST printing mitigates this a little by at least indicating
that the enum has become a nested "Code" type.