- getAsDeclOrDeclExtensionContext -> getAsDecl
This is basically the same as a dyn_cast, so it should use a 'getAs'
name like TypeBase does.
- getAsNominalTypeOrNominalTypeExtensionContext -> getSelfNominalTypeDecl
- getAsClassOrClassExtensionContext -> getSelfClassDecl
- getAsEnumOrEnumExtensionContext -> getSelfEnumDecl
- getAsStructOrStructExtensionContext -> getSelfStructDecl
- getAsProtocolOrProtocolExtensionContext -> getSelfProtocolDecl
- getAsTypeOrTypeExtensionContext -> getSelfTypeDecl (private)
These do /not/ return some form of 'this'; instead, they get the
extended types when 'this' is an extension. They started off life with
'is' names, which makes sense, but changed to this at some point. The
names I went with match up with getSelfInterfaceType and
getSelfTypeInContext, even though strictly speaking they're closer to
what getDeclaredInterfaceType does. But it didn't seem right to claim
that an extension "declares" the ClassDecl here.
- getAsProtocolExtensionContext -> getExtendedProtocolDecl
Like the above, this didn't return the ExtensionDecl; it returned its
extended type.
This entire commit is a mechanical change: find-and-replace, followed
by manual reformatted but no code changes.
This saves us some expensive cross-referencing and caching in the runtime, and lets us reclaim the `isReflectable` bit from the context descriptor flags (since a null field descriptor is a suitable and more accurate indicator of whether a type is reflectable).
Certain uses of protocols only formally need the requirement
signature, not any of the method requirements. This results in IRGen
seeing a protocol where none of the members have been validated except
the associated types. Account for this by allowing ProtocolInfo to
only contain the layout for the base protocols and associated types,
if requested.
Note that this relies on the layout of a witness table always putting
the "requirement signature part" at the front, or at least at offsets
that aren't affected by function requirements.
rdar://problem/43260117
We’re not using this parameter, and don’t expect to do so in the future,
so remove it. Also fold away TypeBase::usesNativeReferenceCounting()
and irgen::getReferenceCountingForType(), both of which are trivial.
We don't need to substitute the superclass type as we walk up a
class hierarchy, or look up the generic parameters and conformances
to check if they're concrete, since we're always just emitting
null pointers in place of the generic parameters and requirements,
to be filled at runtime.
Also, don't leave space for generic parameters and requirements from
Objective-C superclasses, since that's not how they're represented.
The type info for a class described its layout using a combination of a
StructLayout and ClassLayout, with different information stored in both.
Since we never use a class as a struct, it's simpler to add the relevant
bits to ClassLayout, and not build a StructLayout at all.
Also, drop inherited properties from the ClassLayout -- they're no
longer needed.
When emitting fixed class metadata, we emit field offsets for all fields,
including those from superclasses, if any.
Get the ClassLayout for the correct class before looking up a field that
might potentially belong to a superclass. Soon, I'm going to slim down
ClassLayout instances to only store the fields belonging to the class
itself, removing the InheritedStoredProperites array altogether.
- Instead of keeping multiple flags in the type descriptor flags,
just keep a single flag indicating the presence of additional
import information after the name.
- That import information consists of a sequence of null-terminated
C strings, terminated by an empty string (i.e. by a double null
terminator), each prefixed with a character describing its purpose.
- In addition to the symbol namespace and related entity name,
include the ABI name if it differs from the user-facing name of the
type, and make the name the user-facing Swift name.
There's a remaining issue here that isn't great: we don't correctly
represent the parent relationship between error types and their codes,
and instead we just use the Clang module as the parent. But I'll
leave that for a later commit.
- `swift_getForeignTypeMetadata` is now a request/response function.
- The initialization function is now a completion function, and the
pointer to it has moved into the type descriptor.
- The cache variable is no longer part of the ABI; it's an
implementation detail of the access function.
- The two points above mean that there is no special header on foreign
type metadata and therefore that they can be marked constant when
there isn't something about them that needs to be initialized.
The only foreign-metadata initialization we actually do right now is
of the superclass field of a foreign class, and since that relationship
is a proper DAG, it's not actually possible to have recursive
initialization problems. But this is the right long-term thing to do,
and it removes one of the last two clients of once-based initialization.
As part of this, rename TypeMetadataRecordKind to TypeReferenceKind
and consistently give it three bits of storage.
The better modelling of these type references appears to have been
sufficient to make dynamic conformance checks succeed, which is good
but unexpected.
The central thrust of this patch is to get these metadata initializations
off of `swift_once` and onto the metadata-request system where we can
properly detect and resolve dependencies. We do this by first introducing
runtime support for resolving metadata requests for "in-place"
initializations (committed previously) and then teaching IRGen to actually
generate code to use them (this patch).
A non-trivial amount of this patch is just renaming and refactoring some of
existing infrastructure that was being used for in-place initializations to
try to avoid unnecessary confusion.
The remaining cases that are still using `swift_once` resolution of
metadata initialization are:
- non-generic classes that can't statically fill their superclass or
have resilient internal layout
- foreign type metadata
Classes require more work because I'd like to switch at least the
resilient-superclass case over to using a pattern much more like what
we do with generic class instantiation. That is, I'd like in-place
initialization to be reserved for classes that actually don't need
relocation.
Foreign metadata should also be updated to the request/dependency scheme
before we declare ABI stability. I'm not sure why foreign metadata
would ever require a type to be resolved, but let's assume it's possible.
Fixes part of SR-7876.
Rather than storing a mangled name in a Swift protocol descriptor,
which encodes information that is redundant with the context of the
protocol, store an unmangled name as in nominal type descriptors. Update
the various places where this name is used to extract the demangle
tree from the context descriptors.
Reimplement protocol descriptors for Swift protocols as a kind of
context descriptor, dropping the Objective-C protocol compatibility
layout. The new protocol descriptors have several advantages over the
current implementation:
* They drop all of the unused fields required for layout-compatibility
with Objective-C protocols.
* They encode the full requirement signature of the protocol. This
maintains more information about the protocol itself, including
(e.g.) correctly encoding superclass requirements.
* They fit within the general scheme of context descriptors, rather than
being their own thing, which allows us to share more code with
nominal type descriptors.
* They only use relative pointers, so they’re smaller and can be placed
in read-only memory
Implements rdar://problem/38815359.
For now, the accessors have been underscored as `_read` and `_modify`.
I'll prepare an evolution proposal for this feature which should allow
us to remove the underscores or, y'know, rename them to `purple` and
`lettuce`.
`_read` accessors do not make any effort yet to avoid copying the
value being yielded. I'll work on it in follow-up patches.
Opaque accesses to properties and subscripts defined with `_modify`
accessors will use an inefficient `materializeForSet` pattern that
materializes the value to a temporary instead of accessing it in-place.
That will be fixed by migrating to `modify` over `materializeForSet`,
which is next up after the `read` optimizations.
SIL ownership verification doesn't pass yet for the test cases here
because of a general fault in SILGen where borrows can outlive their
borrowed value due to being cleaned up on the general cleanup stack
when the borrowed value is cleaned up on the formal-access stack.
Michael, Andy, and I discussed various ways to fix this, but it seems
clear to me that it's not in any way specific to coroutine accesses.
rdar://35399664
In a generic requirement, distinguish between Swift and
Objective-C protocols using a spare bit within the relative
(indirectable) reference to the protocol.
If we only emit an opaque reflection record for a struct or class, then we can't reflect its fields. We failed both to clear the "is reflectable" bit in the context descriptor for non-reflectable structs, and to check for the bit before trying to present a struct's fields as children in the runtime. rdar://problem/41274260
Clang-importer-synthesized declarations get an extra tag character included in their mangling, which was not being preserved in type context descriptors. This caused runtime lookup for these synthesized types to fail. Fix this by adding the tag information to type context descriptors and teaching the runtime to match it up when fetching metadata by mangled name. Fixes rdar://problem/40878715.
Introduce some metaprogramming of accessors and generally prepare
for storing less-structured accessor lists.
NFC except for a change to the serialization format.
Type of elements contained by field offsets vector can be adjusted
to 32-bit integers (from being pointer sized) to safe space in the
binary since segment size is limited to 4 GB.
Resolves: rdar://problem/36560486
Most of the work of this patch is just propagating metadata states
throughout the system, especially local-type-data caching and
metadata-path resolution. It took a few design revisions to get both
DynamicMetadataRequest and MetadataResponse to a shape that felt
right and seemed to make everything easier.
The design is laid out pretty clearly (I hope) in the comments on
DynamicMetadataRequest and MetadataResponse, so I'm not going to
belabor it again here. Instead, I'll list out the work that's still
outstanding:
- I'm sure there are places we're asking for complete metadata where
we could be asking for something weaker.
- I need to actually test the runtime behavior to verify that it's
breaking the cycles it's supposed to, instead of just not regressing
anything else.
- I need to add something to the runtime to actually force all the
generic arguments of a generic type to be complete before reporting
completion. I think we can get away with this for now because all
existing types construct themselves completely on the first request,
but there might be a race condition there if another asks for the
type argument, gets an abstract metadata, and constructs a type with
it without ever needing it to be completed.
- Non-generic resilient types need to be switched over to an IRGen
pattern that supports initialization suspension.
- We should probably space out the MetadataStates so that there's some
space between Abstract and Complete.
- The runtime just calmly sits there, never making progress and
permanently blocking any waiting threads, if you actually form an
unresolvable metadata dependency cycle. It is possible to set up such
a thing in a way that Sema can't diagnose, and we should detect it at
runtime. I've set up some infrastructure so that it should be
straightforward to diagnose this, but I haven't actually implemented
the diagnostic yet.
- It's not clear to me that swift_checkMetadataState is really cheap
enough that it doesn't make sense to use a cache for type-fulfilled
metadata in associated type access functions. Fortunately this is not
ABI-affecting, so we can evaluate it anytime.
- Type layout really seems like a lot of code now that we sometimes
need to call swift_checkMetadataState for generic arguments. Maybe
we can have the runtime do this by marking low bits or something, so
that a TypeLayoutRef is actually either (1) a TypeLayout, (2) a known
layout-complete metadata, or (3) a metadata of unknown state. We could
do that later with a flag, but we'll need to at least future-proof by
allowing the runtime functions to return a MetadataDependency.
These will be used as lookup keys for order-independent witness
table instantiation. In the future, a reflective call mechanism
could make use of this metadata as well.