Start fixing SR-12526: `@derivative` attribute cross-module deserialization
crash. Remove original `AbstractFunctionDecl *` from `DerivativeAttr` and store
`DeclID` instead, mimicking `DynamicReplacementAttr`.
Type erasure requires a circular construction by its very nature:
@_typeEraser(AnyProto)
protocol Proto { /**/ }
public struct AnyProto : Proto {}
If we eagerly resolve AnyProto, the chain of resolution steps that
deserialization must make goes a little something like this:
Lookup(Proto)
-> Deserialize(@_typeEraser(AnyProto))
-> Lookup(AnyProto)
-> DeserializeInheritedStuff(AnyProto)
-> Lookup(Proto)
This cycle could be broken if the order of incremental inputs was
such that we had already cached the lookup of Proto.
Resolve this cycle in any case by suspending the deserialization of the
type eraser until the point it's demanded by adding
ResolveTypeEraserTypeRequest.
rdar://61270195
Recent clang side change merges ObjCCategoryDecl with the same name. All re-declarations
of a category points to the first category as the canonical one. This patch keeps these
non-canonical redeclarations as separate extensions in Swift.
rdar://problem/59744309
As part of this, we have to change the type export rules to
prevent `@convention(c)` function types from being used in
exported interfaces if they aren't serializable. This is a
more conservative version of the original rule I had, which
was to import such function-pointer types as opaque pointers.
That rule would've completely prevented importing function-pointer
types defined in bridging headers and so simply doesn't work,
so we're left trying to catch the unsupportable cases
retroactively. This has the unfortunate consequence that we
can't necessarily serialize the internal state of the compiler,
but that was already true due to normal type uses of aggregate
types from bridging headers; if we can teach the compiler to
reliably serialize such types, we should be able to use the
same mechanisms for function types.
This PR doesn't flip the switch to use Clang function types
by default, so many of the clang-function-type-serialization
FIXMEs are still in place.
Lazy loading checked if the ClangDecl was hidden, but loading all
members did not. Let's make loadAllMembers() behave like the lazy
path, and fix some of the mock SDKs in the test suite.
We would add all imported members to a per-nominal vector, and
then perform shadowing checks on the entire list, followed by
visiting each one to look for a matching member with the
right name.
We were spending a lot of time inside this function as a result.
Instead, change Impl.MembersForNominal to store a mapping from
names to lists of members having that name, changing this into
an O(1) lookup.
Fixes <rdar://problem/58363207>.
Push some state closer to where it's actually needed and remove helper functions that aren't actually all that helpful. Replace these with an assertion for the real invariant here.
This is primarily meant to used for testing LLDB's DWARFImporterDelegate,
however, this could become the default option for LLDB once
DWARFImporterDelegate is sufficiently mature.
<rdar://problem/57880844>
The general problem with this approach is that the clang importer is part of the cache-fill for name lookup. This means that qualified lookups it runs will be re-entrant and result in validation-order-dependent behaviors.
The next commit will restore the expected ordering behavior here.
To support lazy resolution of the cross-referenced function in a serialized @_dynamicReplacement(for: ...) attribute, add a utility to the LazyMemberLoader and plumb it through. This is a more general utility than the current resolver, which relies on the type checker to strip the attribute off of VarDecls and fan it back out onto accessors, which means serialization has only ever seen AbstractFunctionDecls.
The only thing this was used for is to test if the total number of
parameters was 1, in which case we did the same thing we did for a
first parameter except in one very contrived case: a method with more
than one parameter whose base name starts with "set" and whose first
parameter is an NSZone. There are zero of these in the macOS or iOS
SDKs, and probably even fewer in third-party code.
1. Set the diagnostic location to where the attribute was written (or
to the Clang decl's source, if the attribute came from API notes)
2. Add a note to contact the owners of the framework to make it clear
that the client of the framework didn't do anything wrong.
rdar://problem/52736145
Emitting Swift diagnostics in Clang buffers requires making those
buffers valid places to put Swift SourceLocs, which means making a
mirror of those buffers in the Swift SourceManager. This isn't a copy;
instead, any Clang SourceManagers that are involved are kept alive
until the importer is torn down. (There might be more than one because
of diagnostics emitted during module building.)
For a long time we only emitted diagnostics in Clang buffers if the
diagnostics came from Clang, but then we added another case for custom
Swift names that fail to import. I'm about to add another such
diagnostic, so let's formalize this buffer mapping first.
No intended functionality change.
Structurally prevent a number of common anti-patterns involving generic
signatures by separating the interface into GenericSignature and the
implementation into GenericSignatureBase. In particular, this allows
the comparison operators to be deleted which forces callers to
canonicalize the signature or ask to compare pointers explicitly.
...rather than replacing particular macros with an 'annotate'
attribute and then looking for that. This isn't /really/ any
particular win except maybe ever-so-slightly faster module imports
(with one fewer attribute being added to each declaration in a
mixed-source header).
This doesn't remove the SWIFT_CLASS_EXTRA, SWIFT_PROTOCOL_EXTRA, or
SWIFT_ENUM_EXTRA macros from PrintAsObjC (note that
SWIFT_EXTENSION_EXTRA was never used). They're not exactly needed
anymore, but they're not doing any harm if someone else is using them.
And similar for importFunctionParamsAndReturnType and
importAccessorParamsAndReturnType. In all cases the return type isn't
a FunctionType, and there's also a ParameterList out-parameter.
No functionality change.
Back when IUO could be used anywhere in a type in Swift, we had a
special case for imported pointer types that their pointees were never
implicitly-unwrapped, even if they weren't nullability-audited on the
Objective-C side. Now that IUO can only be used in top-level positions
(SE-0054, only fully implemented last year), we don't need a special
case for this; all non-top-level optionals are never
implicitly-unwrapped.
No functionality change.
A typedef might get imported as an alias for a bridged type (String)
or for the original type (NSString), and a few parts of the importer
need to account for this. Simplify this logic based on how it's used
today.
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.
This eliminates the entire 'lazy generic environment' concept;
essentially, all generic environments are now lazy, and since
each signature has exactly one environment, their construction
no longer needs to be co-ordinated with deserialization.
This avoids a re-entrant lookup while doing lazy member loading,
and eliminates a usage of LookupDirectFlags::IgnoreNewExtensions,
and the last usage of NominalTypeDecl::makeMemberVisible().