This API is meant to enable people working in SIL to be able to retrieve the
type lowering of a lowered type within the GenericSignature associated with a
given SILFunction's SILFunctionType.
Formal types are defined by the language's type system. SIL types are
lowered. They are no longer part of that type system.
The important distinction here is between the SIL storage type and the SIL value
type. To make this distinction clear, I refer to the SILFunctionTypes "formal"
conventions. These conventions dictate the SIL storage type but *not* the SIL
value type. I call them "formal" conventions because they are an immutable
characteristic of the function's type and made explicit via qualifiers on the
function type's parameters and results. This is in contrast to to SIL
conventions which depend on the SIL stage, and in the short term whether the
opaque values flag is enabled.
Separate formal lowered types from SIL types.
The SIL type of an argument will depend on the SIL module's conventions.
The module conventions are determined by the SIL stage and LangOpts.
Almost NFC, but specialized manglings are broken incidentally as a result of
fixes to the way passes handle book-keeping of aruments. The mangler is fixed in
the subsequent commit.
Otherwise, NFC is intended, but quite possible do to rewriting the logic in many
places.
This also avoids undefined behavior when we try to look up the
ParameterConvention of a type dependent operand. Since type dependent operands
do not have a convention, this causes us to hit an assertion.
rdar://29791263
This is only enabled when semantic sil is enabled /and/ we are not parsing
unqualified SIL.
*NOTE* To properly write tests for this, I had to rework how we verified
Branch/CondBranch insts to be actually correct (instead of pseudo-correct). I
have to put this functionality together in order to write tests.
rdar://29791263
The reason why I am introducing special instructions is so I can maintain the
qualified ownership API wedge in between qualified SIL and the rest of the ARC
instructions that are pervasively used in the compiler.
These instructions in the future /could/ be extended to just take @sil_unmanaged
operands directly, but I want to maintain flexibility to take regular
non-trivial operands in the short term.
rdar://29791263
A witness table is dead if it is not used outside the module (private/internal) and it’s not used by any instruction or other witness table in the module.
Also the meta-type of the conforming type must not escape, because it’s possible to test any opaque type if it conforms to a protocol.
rdar://problem/23026019
Most of this involved sprinkling ValueOwnershipKind::Owned in many places. In
some of these places, I am sure I was too cavalier and I expect some of them to
be trivial. The verifier will help me to track those down.
On the other hand, I do expect there to be some places where we are willing to
accept guaranteed+trivial or owned+trivial. In those cases, I am going to
provide an aggregate ValueOwnershipKind that will then tell SILArgument that it
should disambiguate using the type. This will eliminate the ackwardness from
such code.
I am going to use a verifier to fix such cases.
This commit also begins the serialization of ValueOwnershipKind of arguments,
but does not implement parsing of value ownership kinds. That and undef are the
last places that we still use ValueOwnershipKind::Any.
rdar://29791263
This in the case of insertFunctionArgument requires a ValueOwnershipKind to be
specified since we use that for transformations of function argument lists that
are only correct after the transformation is complete. This only occurs in
FunctionSignatureOptimizations.
On the other hand, createFunctionArgument is only used to construct completely
new argument lists, so we can instead just rely on the function we are in rather
than require the user to pass it in.
rdar://29791263
This is dead code and can be re-added if it is needed. Right now though there
really isnt a ValueOwnershipKind that corresponds to deallocating and I do not
want to add a new ValueOwnershipKind for dead code.
The typedef `swift::Module` was a temporary solution that allowed
`swift::Module` to be renamed to `swift::ModuleDecl` without requiring
every single callsite to be modified.
Modify all the callsites, and get rid of the typedef.
For this we need to store the linkage of the “original” method implementation in the vtable.
Otherwise DeadFunctionElimination thinks that the method implementation is not public but private (which is the linkage of the thunk).
The big part of this change is to extend SILVTable to store the linkage (+ serialization, printing, etc.).
fixes rdar://problem/29841635
If a Swift type T needs to be casted to a CF type, then we first cast T to its bridged NS type and then ref_cast the result to a corresponding CF type.
For example, if we need to cast String to CFString, we first cast String to NSString and then ref_cast the NSString to CFString.
Fixes rdar://problem/29745498
Not sure why but this was another "toxic utility method".
Most of the usages fell into one of three categories:
- The base value was always non-null, so we could just call
getCanonicalType() instead, making intent more explicit
- The result was being compared for equality, so we could
skip canonicalization and call isEqual() instead, removing
some boilerplate
- Utterly insane code that made no sense
There were only a couple of legitimate uses, and even there
open-coding the conditional null check made the code clearer.
Also while I'm at it, make the SIL open archetypes tracker
more typesafe by passing around ArchetypeType * instead of
Type and CanType.
This means using a struct so we can put methods on the struct and using an
anonymous enum to create namespaced values. Specifically:
struct SILArgumentConvention {
enum : uint8_t {
Indirect_In,
Indirect_In_Guaranteed,
Indirect_Inout,
Indirect_InoutAliasable,
Indirect_Out,
Direct_Owned,
Direct_Unowned,
Direct_Deallocating,
Direct_Guaranteed,
} Value;
SILArgumentConvention(decltype(Value) NewValue)
: Value(NewValue) {}
operator decltype(Value)() const {
return Value;
}
ParameterConvention getParameterConvention() const {
switch (Value) {
...
}
}
bool isIndirectConvention() const {
...
}
};
This allows for:
1. Avoiding abstraction leakage via the enum type. If someone wants to use
decltype as well, I think that is enough work that the leakage is acceptable.
2. Still refer to enum cases like we are working with an enum class
(e.g. SILArgumentConvention::Direct_Owned).
3. Avoid using the anonymous type in function arguments due to an implicit
conversion.
4. And most importantly... *drum roll* add methods to our enums!