This reorganization allows adding attributes that refer to types.
I need this for a @_specialize attribute with a type list.
PrintOptions.h and other headers depend on these enums. But Attr.h
defines a lot of classes that almost never need to be included.
Fix some interface type/context type confusion in the AST synthesis from the previous patch, add a unique private mangling for behavior protocol conformances, and set up SILGen to emit the conformances when property declarations with behaviors are visited. Disable synthesis of the struct memberwise initializer if any instance properties use behaviors; codegen will need to be redesigned here.
This prevents the linker from trying to emit relative relocations to locally-defined public symbols into dynamic libraries, which gives ld.so heartache.
IRGen now uses a ConstantBuilder to build protocol metadata, which may
now have additional fields at the end for default witnesses.
For now, the default implementations in the test have to external
because IRGen cannot emit a witness_method body where Self is
abstract. I will fix this by passing in the witness table as part
of the witness_method calling convention.
On the IRGen side, other than the calling convention change, the only
remaining piece here is emitting GenericWitnessTables and accessor
functions for conformances where the conformance is defined in
a different module than the protocol, and the protocol is resilient.
Sema still needs to infer default witnesses and store them in the
ProtocolDecl, so that SILGen can emit default witness thunks for
them.
This is the first patch in a series that will allow new protocol
requirements to be added resiliently, with the runtime filling in
default implementations in witness tables.
First, this adds a new flag to the protocol descriptor indicating
that the protocol is resilient. In this case, there are two
additional fields, MinimumWitnessTableSizeInWords and
DefaultWitnessTableSizeInWords, followed by tail-allocated
default witnesses.
The swift_getGenericWitnessTable() entry point now fills in the
default witnesses from the protocol if the given witness table
template is smaller than the expected witness table size.
This also changes the layout of instantiated witness tables to move
the address point to the end of private data. Previously the private
data came after the requirements, but this meant that adding new
requirements would require sliding the private data at runtime and
accessing it indirectly. It is much simpler to access it from
negative offsets instead.
I updated IRGen to emit the new metadata, but currently all protocols
are flagged as not resilient, and default witnesses are not emitted;
this will come in a subsequent patch once some more plumbing is
in place.
To avoid generating GOT entries for references to protocols defined
in the current module, I had to add some hacks to the existing hack
for this. I'll hopefully clean this up in a principled manner later.
- Implement emission of type references for nominal type field
reflection, using a small custom encoder resulting in packed
structs, not strings. This will let us embed 7-bit encoded
32-bit relative offsets directly in the structure (not yet
hooked in).
- Use the AST Mangler for encoding type references
Archetypes and internal references were complicating this before, so we
can take the opportunity to reuse this machinery and avoid unique code
and new ABI.
Next up: Tests for reading the reflection sections and converting the
demangle tree into a tree of type references.
Todo: For concrete types, serialize the types for associated types of
their conformances to bootstrap the typeref substitution process.
rdar://problem/15617914
This comes with a fix for a null pointer dereference in _typeByName()
that would pop with foreign classes that do not have a
NominalTypeDescriptor.
Also, I decided to back out part of the change for now, where the
NominalTypeDescriptor references an accessor function instead of a
pattern, since this broke LLDB, which reaches into the pattern to
get the generic cache.
Soon we will split off the generic cache from the pattern, and at
that time we can change the NominalTypeDescriptor to point at the
cache. But for now, let's avoid needless churn in LLDB by keeping
that part of the setup unchanged.
Change conformance records to reference NominalTypeDescriptors instead of
metadata patterns for resilient or generic types.
For a resilient type, we don't know if the metadata is constant or not,
so we can't directly reference either constant metadata or the metadata
template.
Also, whereas previously NominalTypeDescriptors would point to the
metadata pattern, they now point to the metadata accessor function.
This allows the recently-added logic for instantiating concrete types
by name to continue working.
In turn, swift_initClassMetadata_UniversalStrategy() would reach into
the NominalTypeDescriptor to get the pattern out, so that its bump
allocator could be used to allocate ivar tables. Since the pattern is
no longer available this way, we have to pass it in as a parameter.
In the future, we will split off the read-write metadata cache entry
from the pattern; then swift_initClassMetadata_UniversalStrategy() can
just take a pointer to that, since it doesn't actually need anything
else from the pattern.
Since Clang doesn't guarantee alignment for function pointers, I had
to kill the cute trick that packed the NominalTypeKind into the low
bits of the relative pointer to the pattern; instead the kind is now
stored out of line. We could fix this by packing it with some other
field, or keep it this way in case we add new flags later.
Now that generic metadata is instantiated by calling accessor functions,
this change removes the last remaining place that metadata patterns were
referenced from outside the module they were defined in. Now, the layout
of the metadata pattern and the behavior of swift_getGenericMetadata()
is purely an implementation detail of generic metadata accessors.
This patch allows two previously-XFAIL'd tests to pass.
Make sure to set the linkage correctly, treat the selector data as
non-constant, note that it is externally-initialized, and add it to
llvm.compiler.used rather than llvm.used.
Instead of directly emitting calls to swift_getGenericMetadata*() and
referencing metadata templates, call a metadata accessor function
corresponding to the UnboundGenericType of the NominalTypeDecl.
The body of this accessor forwards arguments to a runtime metadata
instantiation function, together with the template.
Also, move some code around, so that metadata accesses which are
only done as part of the body of a metadata accessor function are
handled separately in emitTypeMetadataAccessFunction().
Apart from protocol conformances, this means metadata templates are
no longer referenced from outside the module where they were defined.
This is a preliminary refactoring toward emitting generic metadata
instantiation accessors. This will let us stop exporting metadata
template symbols and reference accessors from conformance tables
instead. The latter is required to enable conformances where the
conforming type is resilient.
Decrease the size of nominal type descriptors and make them true-const by relative-addressing the other metadata they need to reference, which should all be included in the same image as the descriptor itself. Relative-referencing string constants exposes a bug in the Apple linker, which crashes when resolving relative relocations to coalesceable symbols (rdar://problem/22674524); work around this for now by revoking the `unnamed_addr`-ness of string constants that we take relative references to. (I haven't tested whether GNU ld or gold also have this problem on Linux; it may be possible to conditionalize the workaround to only apply to Darwin targets for now.)
This reverts commit ccb2de0a39.
Crashes on these tests:
Swift :: Interpreter/class_resilience.swift
Swift :: Interpreter/generic_objc_subclass.swift
Swift :: Interpreter/struct_resilience.swift
This assertion was accidentally removed in the commit below:
<32bd7705bf>
The original purpose of the check was to ensure that unbound generic patterns
are never added to protocol conformance records, only to type metadata records
(where they are present a future implementation of dynamic type
specialization).
We can avoid using a buffer if the global is fixed-size in all
resilience domains that access it directly. This is a more
conservative condition than being fixed-size in all resilience
domains.
This was fixed by Luke Howard as part of some other changes in the
following patch:
<b5880f386b>
After rebasing my fix, I noticed most of it disappeared.
However, it's still worth checking in the tests.
Fixes <rdar://problem/24183374>.
replace ProtocolConformanceTypeKind with TypeMetadataRecordKind
metadata reference does not need to be indirectable
more efficient check for protocol conformances
remove swift_getMangledTypeName(), not needed yet
kill off Remangle.cpp for non-ObjC builds
cleanup
cleanup
cleanup comments
This is the first in a series of patches that fixes some resilience-related
issues with synthesized accessors and materializeForSet.
Previously we maintained two lists of external declarations encountered while
type checking:
- ASTContext::ExternalDefinitions
- TypeChecker::implicitlyDefinedFunctions
The former contained the following:
- Imported nominal types from Clang, so that SILGen can emit witness tables
- Functions and variables with Clang decls, so that IRGen can instruct Clang
to emit them
- Synthesized accessors
The latter contained synthesized functions for derived conformances.
Since the second list was not visible outside Sema, we relied on the Clang
importer to add the type that contained the declaration to the
ExternalDefinitions list. In practice, we only synthesized members of enums
in this manner.
Because of this, SILGenModule::emitExternalDefinitions() had special logic to
skip members of enums, since it would visit them when visiting the enum itself.
Instead, it appears that we can remove implicitlyDefinedFunctions completely,
changing usage sites to add the decl to ExternalDefinitions instead, and
simplify SILGenModule::emitExternalDefinition() a bit in the process.
Also, it looks like we never had Modules appear in ExternalDefinitions, so
assert if those come up instead of skipping them.
Allocate and project the buffer, respectively, adding the
necessary indirection required to handle the size not being
known until runtime.
For now we don't emit alloc_global instructions anywhere;
an upcoming change will add that at the SIL level.
Also I suspect debug info needs some work to handle the
extra indirection, I'll look into this soon.
of associated types in protocol witness tables.
We use the global access functions when the result isn't
dependent, and a simple accessor when the result can be cheaply
recovered from the conforming metadata. Otherwise, we add a
cache slot to a private section of the witness table, forcing
an instantiation per conformance. Like generic type metadata,
concrete instantiations of generic conformances are memoized.
There's a fair amount of code in this patch that can't be
dynamically tested at the moment because of the widespread
reliance on recursive expansion of archetypes / dependent
types. That's something we're now theoretically in a position
to change, and as we do so, we'll test more of this code.
This speculatively re-applies 7576a91009,
i.e. reverts commit 11ab3d537f.
We have not been able to duplicate the build failure in
independent testing; it might have been spurious or unrelated.
of associated types in protocol witness tables.
We use the global access functions when the result isn't
dependent, and a simple accessor when the result can be cheaply
recovered from the conforming metadata. Otherwise, we add a
cache slot to a private section of the witness table, forcing
an instantiation per conformance. Like generic type metadata,
concrete instantiations of generic conformances are memoized.
There's a fair amount of code in this patch that can't be
dynamically tested at the moment because of the widespread
reliance on recursive expansion of archetypes / dependent
types. That's something we're now theoretically in a position
to change, and as we do so, we'll test more of this code.
This reverts commit 6528ec2887, i.e.
it reapplies b1e3120a28, with a fix
to unbreak release builds.
The runtime entry doesn't just report the error, unlike the other report* functions, it also does the crashing.
Reapplying independent of unrelated reverted patches.
This reverts commit b1e3120a28.
Reverting because this patch uses WitnessTableBuilder::PI in NDEBUG code.
That field only exists when NDEBUG is not defined, but now NextCacheIndex, a
field that exists regardless, is being updated based on information from PI.
This problem means that Release builds do not work.
of associated types in protocol witness tables.
We use the global access functions when the result isn't
dependent, and a simple accessor when the result can be cheaply
recovered from the conforming metadata. Otherwise, we add a
cache slot to a private section of the witness table, forcing
an instantiation per conformance. Like generic type metadata,
concrete instantiations of generic conformances are memoized.
There's a fair amount of code in this patch that can't be
dynamically tested at the moment because of the widespread
reliance on recursive expansion of archetypes / dependent
types. That's something we're now theoretically in a position
to change, and as we do so, we'll test more of this code.
If an enum case has a payload but the unsubstituted payload type is
zero-sized, we would convert the case into a no-payload case.
This was valid when the only invariant that had to be preserved
is that an enum's layout is the same between all substitutions
of a generic type.
However this is now wrong if the payload type is resiliently-sized,
because other resilience domains may not have knowledge that it is
zero-sized.
The new utility methods will also be used in class layout.