Like the last commit, SourceFile is used a lot by Parse and Sema, but
less so by the ClangImporter and (de)Serialization. Split it out to
cut down on recompilation times when something changes.
This commit does /not/ split the implementation of SourceFile out of
Module.cpp, which is where most of it lives. That might also be a
reasonable change, but the reason I was reluctant to is because a
number of SourceFile members correspond to the entry points in
ModuleDecl. Someone else can pick this up later if they decide it's a
good idea.
No functionality change.
Computing the interface type of a typealias used to push validation forward and recompute the interface type on the fly. This was fragile and inconsistent with the way interface types are computed in the rest of the decls. Separate these two notions, and plumb through explicit interface type computations with the same "computeType" idiom. This will better allow us to identify the places where we have to force an interface type computation.
Also remove access to the underlying type loc. It's now just a cache location the underlying type request will use. Push a type repr accessor to the places that need it, and push the underlying type accessor for everywhere else. Getting the structural type is still preferred for pre-validated computations.
This required the resetting of a number of places where we were - in many cases tacitly - asking the question "does the interface type exist". This enables the removal of validateDeclForNameLookup
Removes duplicated logic from the implementations of
FileUnit::lookupValue, and simplifies the interface to
ModuleDecl::lookupValue, where everyone was passing an empty
(non-filtering) access path anyway /except/ during actual lookup from
source code. No functionality change.
The weak imported flag is now only set if the attribute is unconditionally
weak linked, which is the case when it or one of its parent contexts has a
@_weakLinked attribute.
To correctly handle weak linking based availability with serialized SIL
functions, we need to serialize the actual version tuple when the SIL function
was introduced. This is because the deployment target of the client app can
be older than the deployment target that the original module was built with.
Fixes <rdar://problem/52783668>.
Now that GenericSignatures store their single unique GenericEnvironment,
we can remove similar logic from deserialization to preserve identity
of GenericEnvironments.
Instead of computing it from the extended type after deserialization --
which is tricky to do, due to potential presence of protocol
compositions -- we obtain the extended nominal directly.
Fixes SR-11227 and linked rdar://problem/53712389.
...fulfilling the promised audit from 0747d9a339. No intended
functionality change /other/ than the order of already-unsorted lists.
This affected a number of SIL tests that relied on deserialization
order matching the original source order; I have no idea why the old
hash logic would make that the case. If we think that's a valuable
property, we should serialize a list of functions in addition to the
iterable table. (Maybe just in SIB mode?)
A generic environment is always serialized as a GenericSignature with
a lazily-recreated environment, though sometimes it has to include
extra info specifically for generic environments used by SIL. The code
that was doing this claimed a bit for disambiguating between the two,
shrinking the permitted size of a compiled module from 2^31 bits to
2^30. (The code isn't just needlessly complicated; GenericEnvironments
used to be serialized with more information.)
Rather than have two representations for GenericEnvironmentID, this
commit just drops it altogether in favor of referencing
GenericSignatures directly. This causes a negligible file size
shrinkage for swiftmodules in addition to eliminating the problematic
disambiguation bit.
For now, the Deserialization logic will continue to cache
GenericEnvironments that are used directly by Deserialization, but
really that should probably be done at the AST level. Then we can
simplify further to ModuleFile tracking a plain list of
GenericSignatures.
...by making it a tagged union of either a DeclID or a
LocalDeclContextID. This should lead to smaller module files and be
slightly more efficient to deserialize, and also means that every
AST entity kind is serialized in exactly one way, which allows for
the following commit's refactoring.
Rather than storing the set of input requirements in a
(SIL)SpecializeAttr, store the specialized generic signature. This
prevents clients from having to rebuild the same specialized generic
signature on every use.
The AST block in a compiled module represents an object graph, which
is essentially serialized in four steps:
- An entity (such as a Decl or Type) is encountered, given an ID, and
added to a worklist.
- The next entity is popped from the worklist and its offset in the
output stream is recorded.
- During the course of writing that entity, more entities will be
referenced and added to the worklist.
- Once the entire worklist is drained, the offsets get written to a
table in the Index block.
The implementation of this was duplicated for each kind of entity in
the AST block; this commit factors that out into a reusable helper.
No intended high-level functionality change, but the order in which
Decls and Types get emitted might change a little now that they're not
in the same queue.
- Use Optional::getValueOr instead of a handrolled version.
- Use swift::reversed for reverse iteration instead of reversing a
buffer mutably.
- Use StringRef::withNullAsEmpty instead of checking both kinds of
empty string
We used to track final-ness separately from FinalAttr, but
serialization didn't know how to handle that, so we synthesized a fake
FinalAttr. However, final-ness (finality, I guess) is always kept in
sync with FinalAttr now, so this check is no longer necessary.
No functionality change.
Double-underscored names are reserved for the C++ "implementation"
(language and standard library). Even though "__Consuming" isn't
likely to be part of the C++ standard any time soon, we should follow
the rules.
Note that the API digester will continue to use the string
"__Consuming" for now, even though the underscores aren't really
significant, to avoid invalidating existing dumps.
No functionality change.
This means that we no longer have the invariant that the extendedType always
contains the generic parameters. So we need to fix the assertions/test cases
for it.
The only place this was used in Decl.h was the failability kind of a
constructor.
I decided to replace this with a boolean isFailable() bit. Now that
we have isImplicitlyUnwrappedOptional(), it seems to make more sense
to not have ConstructorDecl represent redundant information which
might not be internally consistent.
Most callers of getFailability() actually only care if the result is
failable or not; the few callers that care about it being IUO can
check isImplicitlyUnwrappedOptional() as well.
We might have an opaque return type path piece after a generic type
param type, so make sure to emit the XREF entry before the opaque return
type path piece as well.
Fixes rdar://53958358
Since the return value of getAccessor() depends on mutable state, it
does not make sense in the request evaluator world. Let's begin by
removing some utility methods derived from getAccessor(), replacing
calls to them with calls to getAccessor().
Implicit accessors are sometimes transparent for performance reasons.
Previously this was done in Sema by maybeMarkTransparent(), which would
add a TransparentAttr. Replace this with a request.
Accessors logically belong to their storage and can be synthesized
on the fly, so removing them from the members list eliminates one
source of mutability (but doesn't eliminate it; there are also
witnesses for derived conformances, and implicit constructors).
Since a few ASTWalker implementations break in non-trivial ways when
the traversal is changed to visit accessors as children of the storage
rather than peers, I hacked up the ASTWalker to optionally preserve
the old traversal order for now. This is ugly and needs to be cleaned up,
but I want to avoid breaking _too_ much with this commit.
Once accessors are no longer listed as members of their parent context,
a failure to deserialize a VarDecl or SubscriptDecl needs to create a
MissingMemberDecl with the total number of vtable entries expected for
all of the accessors of the storage.
Note that until the accessor change actually lands, we always compute
the expected number of vtable entries as 0.
...which allows the AST printer to correctly choose whether to print
it, which means it can be printed in a module interface in a non-WMO
build, which is necessary for @objc enums to have a correct run-time
representation when clients use that interface.
rdar://problem/53469608
Previously we would copy this attribute from a superclass to the
subclass when validating a subclass. However, this is only correct
if the superclass is always guaranteed to have been validated
before the subclass.
Indeed, it appears this assumption is no longer true, so we would
sometimes lose track of the attribute, which would result in SILGen
failing to emit the ivar initializer entry point.
Instead, check for the attribute as part of the superclass walk
in checkAncestry(), ensuring the result is always up to date, correct,
and cached.
As a follow-up, we should also convert checkAncestry() into a
request, but I'm not doing that here to keep the fix short.
Fixes <rdar://problem/50845438>.
If a protocol inherits from a protocol that can't be loaded, drop it
entirely. Similarly, if it has requirements that reference types in
other modules that can't be loaded, drop the protocol entirely---at
least for now, we don't want to deal with a protocol that exists but
has the wrong requirement signature. That "in other modules" isn't
perfect, but it avoids cases where two protocols depend on each other.
Unfortunately, it means the compiler may still get into exactly the
situation above if a protocol depends on another protocol in the same
module, and /that/ protocol can't be loaded for some other reason. But
it's progress.
This comes up when referencing implementation-only-imported protocols
from non-public protocols, but is also just general deserialization
recovery goodness.
rdar://problem/52141347
When the outermost property wrapper associated with a property has a
`wrapperValue`, create the projection property (with the `$` prefix)
at the same access level as the original property. This puts the
wrapped-value interface and the projection interface at the same level.
The newly-introduced @_projectionValueProperty attribute is implicitly
created to establish the link between the original property and the
projection value within module interfaces, where both properties will
be explicitly written out.
We don't need to serialize the protocol's superclass, we can compute it from the
generic signature. Previously, we would drop the superclass while
serializing because we didn't check the generic signature in
SuperclassTypeRequest, which would cause us to cache `NULL` when we
called `setSuperclass` for a protocol with a superclass constraint.
Fixes rdar://50526401
...well, at least a little more than before. This /still/ isn't as
strong as the switch that used to be here because a subtype of an
existing Decl or Type won't show up, but that's probably still worth
the maintainability (and backtrace) tradeoff.