Since I'm in the area, make it clear that this is building a signature
for builtins. Also, I plan to steal the name "GenericSignatureBuilder"
for what is currently the "ArchetypeBuilder" in the near future.
A pointless use of polymorphism -- the result values are not
interchangeable in any practical sense:
- For GenericTypeParamDecls, this returned getDeclaredInterfaceType(),
which is an interface type.
- For AssociatedTypeDecls, this returned the sugared AssociatedTypeType,
which desugars to an archetype.
- For TypeAliasDecls, this returned TypeAliasDecl::getAliasType(),
which desugars to a type containing archetypes.
- For NominalTypeDecls, this returned NominalTypeDecl::getDeclaredType(),
which is the unbound generic type, a special case used for inferring
generic arguments when they're not written in source.
This eliminates the really gross registration of archetype builders
within the ASTContext, and is another little step toward lazily
constructing archetypes.
Stop recording specific archetypes anywhere in
PotentialArchetype. Instead, use a GenericEnvironment to record/query
the archetype that corresponds to that PotentialArchetype, making it
possible to use the same archetype builder (and its potential
archetypes) to build multiple generic environments.
Type substitution works on a fairly narrow set of types: generic type
parameters (to, e.g., use a generic) and archetypes (to map out of a
generic context). Historically, it was also used with
DependentMemberTypes, but recent refactoring to eliminate witness
markers eliminate that code path.
Therefore, narrow TypeSubstitutionMap's keys to SubstitutableType,
which covers archetypes and generic type parameters. NFC
An environment is always associated with a location with a signature, so
having them separate is pointless duplication. This patch also updates
the serialization to round-trip the signature data.
Sugared GenericTypeParamTypes point to GenericTypeParamDecls,
allowing the name of the parameter as written by the user to be
recovered. Canonical GenericTypeParamTypes on the other hand
only store a depth and index, without referencing the original
declaration.
When printing SIL, we wish to output the original generic parameter
names, even though SIL only uses canonical types. Previously,
we used to accomplish this by mapping the generic parameter to an
archetype and printing the name of the archetype. This was not
adequate if multiple generic parameters mapped to the same
archetype, or if a generic parameter was mapped to a concrete type.
The new approach preserves the original sugared types in the
GenericEnvironment, adding a new GenericEnvironment::getSugaredType()
method.
There are also some other assorted simplifications made possible
by this.
Unfortunately this makes GenericEnvironments use a bit more memory,
however I have more improvements coming that will offset the gains,
in addition to making substitution lists smaller also.
There's a bit of a hack to deal with generic typealiases, but
overall this makes things more logical.
This is the last big refactoring before we can allow constrained
extensions to make generic parameters concrete. All that remains
is a small set of changes to SIL type lowering, and retooling
some diagnostics in Sema.
We need the encode string to be able to construct NSValues using the core valueWithBytes:objCType: API. This builtin only works with concrete, @objc-representable types for now, which should be sufficient for a stdlib-internal API.
Those builtins are: allocWithTailElems_<n>, getTailAddr and projectTailElems
Also rename the "gep" builtin, which indexes raw bytes, to "gepRaw" and add a new "gep" builtin to index in a typed array.
id-as-Any lets you pass Optional to an ObjC API that takes `nonnull id`, and also lets you bridge containers of `Optional` to `NSArray` etc. When this occurs, we can unwrap the value and bridge it so that inhabited optionals still pass into ObjC in the expected way, but we need something to represent `none` other than the `nil` pointer. Cocoa provides `NSNull` as the canonical "null for containers" object, which is the least bad of many possible answers. If we happen to have the rare nested optional `T??`, there is no precedented analog for these in Cocoa, so just generate a unique sentinel object to preserve the `nil`-ness depth so we at least don't lose information round-tripping across the ObjC-Swift bridge.
Making Optional conform to _ObjectiveCBridgeable is more or less enough to make this all work, though there are a few additional edge case things that need to be fixed up. We don't want to accept `AnyObject??` as an @objc-compatible type, so special-case Optional in `getForeignRepresentable`.
Implements SR-0140 (rdar://problem/27905315).
Those builtins are: allocWithTailElems_<n>, getTailAddr and projectTailElems
Also rename the "gep" builtin, which indexes raw bytes, to "gepRaw" and add a new "gep" builtin to index in a typed array.
The intrinsics table is now split sorted, with the generic arguments being
lexicographically sorted prior to the target specific intrinsics. Adjust the
search accordingly, as otherwise the builtins are not found as the basis for the
search no longer holds.
Now that SILFunctions no longer reference a GenericParamList, we
don't need to de-serialize cross-module references to archetypes
anymore.
This was the last remaining usage of AllArchetypes, so we can
finally rip it out.
A GenericEnvironment stores the mapping between GenericTypeParamTypes
and context archetypes (or eventually, concrete types, once we allow
extensions to constrain a generic parameter to a concrete type).
The goals here are two-fold:
- Eliminate the GenericTypeParamDecl::getArchetype() method, and
always use mapTypeIntoContext() instead
- Replace SILFunction::ContextGenericParams with a GenericEnvironment
This patch adds the new data type as well as serializer and AST
verifier support. but nothing else uses it yet.
Note that GenericSignature::get() now asserts if there are no
generic parameters, instead of returning null. This requires a
few tweaks here and there.
The intrinsics table is now split sorted, with the generic arguments being
lexicographically sorted prior to the target specific intrinsics. Adjust the
search accordingly, as otherwise the builtins are not found as the basis for the
search no longer holds.
Strict aliasing only applies to memory operations that use strict
addresses. The optimizer needs to be aware of this flag. Uses of raw
addresses should not have their address substituted with a strict
address.
Also add Builtin.LoadRaw which will be used by raw pointer loads.
Previously getInterfaceType() would punt to getType() if no
interface type was set. This patch changes getInterfaceType()
to assert if no interface type is set, and updates various
places to set the interface type explicitly.
This brings us a step closer to removing PolymorphicFunctionType.
The verifier now asserts that Throws, ThrowsLoc and isBodyThrowing()
match up.
Also, add /*Label=*/ comments where necessary to make the long argument
lists easier to read, and cleaned up some inconsistent naming conventions.
I caught a case where ClangImporter where we were passing in a loc as
StaticLoc instead of FuncLoc, but probably this didn't affect anything.
Swift relies on this for now. So create our own. This makes more sense
than trying to add back in the API (which is dead besides the c api) or
use the c api itself. We should probably consider not using a global
context like this.
It is a hint to the optimizer that the code, where this builtin is called, is on the fast path.
Specifically, the inliner takes it into account and increases the assumed benefit for code where the builtin is located.
Compared to the fastPath/slowPath builtins, this builtin can be placed into plain linear code and doesn't need to be used in conditions.
Compared to the @inline(__always) attribute, this builtin has also an effect on the caller function. Let's assume
foo() calls bar() contains onFastPath
and both foo and bar are small functions. Then if bar gets inlined into foo, the builtin also increases the chances that foo gets inlined.
This would not be the case if @inline(__always) is used just for bar.