If the Clang declrations are *types*, canonical declaration in Swift is
imported for newest version of Swift. In interface generation, if the
declaration is versioned and it's imported as a member in either or both
version of Swift, we have to take compatibility typealias into account.
* Fixed 'ClangModuleUnit::getTopLevelDecls' to take isCompatibilityAlias() into account
* Fixed bugs in ClangImporter where member-to-member versioned types aren't properly imported.
* Fixed 'SwiftDeclConverter::importFullName' to check equality of getEffectiveContext()
* Fixed 'importer::addEntryToLookupTable' to check equality of getEffectiveContext()
(moved 'ClangImporter::Implementation::forEachDistinctName' to 'NameImporter')
When the swift_bridged_typedef attribute is present on a typedef,
import the underlying type as bridged (e.g., String) rather than as
its unbridged type (e.g., NSString).
Fixes rdar://problem/39497900.
Rather than relying on the NameAliasType we get by default for references
to non-generic typealiases, use BoundNameAliasType consistently to handle
references to typealiases that are formed by the type checker.
Like 0d347ac1, but for bridging headers. We can have multiple bridging
headers if someone is sneaking them into a library target, even though
we've tried to lock down on that. Up until now we've been pretending
they're all included at offset 0 in the dummy main source file, but
that causes problems in rare occasions involving precompiled headers.
(I'm being vague about what those circumstances are because I haven't
actually nailed them down yet, nor have I reduced the reproducing
project to something that can be checked in as a regression test. But
it's something like "we encountered this header through a particular
include path, but we thought that include path led to a different
header".)
Instead, reuse the fix we had for module imports: a monotonically
increasing include location in a fake (but allocated) buffer. This
will still put the bridging header first under normal circumstances,
but will also handle a mix of module imports and extra bridging
headers being loaded.
rdar://problem/34349832
If a bridging header imported a submodule but /not/ the top-level
module, the top-level module would never be made visible. This is a
problem since the Clang importer makes all top-level decls available
through their enclosing top-level modules, not the individual
submodules.
To fix this, stop special-casing the way we handle bridging header
imports; we can translate them from Clang Modules to Swift ModuleDecls
the same way we do for regular imports.
rdar://problem/37355259
Update several functions to return a Type/bool pair with the bool
representing whether the type is one that should be implicitly
unwrapped. This bool is surfaced up to the decl importing functions,
allowing them to set the appropriate decl attribute so that the
expression type checker will consider selecting the underlying type of
the optional involved during solving if the expression doesn't type
check with the optional type.
When importing Decls, use the IUO information to set the
ImplicitlyUnwrappedOptionalAttr attribute when appropriate.
We're still generating IUO types at the moment, so this change doesn't
really have much of an affect other than the creation of those
attributes.
When loading the named members for a given name, we want to load all
of the members with that base name... not only the ones that match the
full name, because the lookup table is indexed by base name and
filtering too early drops candidates.
Fixes rdar://problem/36085994.
Partially reverts f4f8349 (from July!) which caused us to start
importing global blocks with unbridged parameters, breaking source
compatibility. I'm still investigating whether there's an actual hole
in the logic; see next few commits.
rdar://problem/34913634
...so that we don't have to keep coming back to update it every major
release. And also so we can actually put methods on it instead of
using free functions.
No intended behavior change (yet).
forEachDistinctName might produce the same name for Swift 4 and Swift
5, but it's possible that for some reason the name will only work in
one mode or the other. In that case, even though we're trying the
"same" name again, we still want to invoke the callback once more.
Add a boolean return to the callback to support this.
Tests to come at the end of this patch series -- this shows up when in
Swift 3 mode and the canonical version for types is set to Swift 5.
Preparation for making ImportNameVersion a generalized struct rather
than an enum. We could have kept cramming it into a bitfield, sure,
but we don't actually need this.
No intended functionality change.
"Accessibility" has a different meaning for app developers, so we've
already deliberately excised it from our diagnostics in favor of terms
like "access control" and "access level". Do the same in the compiler
now that we aren't constantly pulling things into the release branch.
This commit changes the 'Accessibility' enum to be named 'AccessLevel'.
This avoids having to bring in all members (and extensions!) for an
outer type just to look up a nested type. In the test case attached
(reduced from the project in SR-5284), this actually led to a circular
dependency between deserialization and the importer, which resulted in
a compiler crash.
This is not a new problem, but it's more important with the release of
Swift 4, where a number of Apple SDK types are now newly imported as
member types. (The one in the original bug was
NSView.AutoresizingMask, formerly NSAutoresizingMaskOptions.) Since we
always use the Swift 4 name for cross-references, this affected
everyone, even those still compiling in Swift 3 mode.
https://bugs.swift.org/browse/SR-5284
Somehow the logic had slipped so that we were basing this decision purely
on the ImportTypeKind and not on whether the broader context is bridgeable.
This was allowing us to use bridged types when e.g. importing the results
and parameters of C function pointer types, which is really bad.
Also, when importing a reference to a typedef of block type, do not use
the typedef in a non-bridgeable context. We import typedefs of block type
as fully-bridged types, but this means that it is invalid to import a type
using the typedef in a context where the original C type must be used.
Similarly, make sure we use a properly-imported underlying type of the
typedef when the typedef itself is unavailable.
Also, extend the special behavior of block typedefs to abstract-function
typedefs, which seems to be consistent with the expected behavior of the
tests.
Finally, I changed importType to take a new Bridgeability enum instead of
a raw canFullyBridgeTypes bool. At the time, I was doing that because I
was going to make it tri-valued; that turned out to be unnecessary, but I
think it's an improvement anyway.
Previously, the importer queued up conformances to complete once it
was done importing the current batch of declarations. However, if
there was a serialized Swift module that extended an imported type to
add a conformance in exactly the wrong way, the importer could end up
asking for that conformance later---even before the reference to the
imported type was resolved. This led to a crash in the deserializer
"while reading conformance for type X".
Instead of this "pending actions" queue, we can just use the
mechanisms already in place for lazily loading conformances. That way
they'll get filled out on demand, which is better all around anyway.
This does mean putting the requirement signature into the "lazy" part
of the conformance, though.
This does as a side effect mean that /all/ of the witnesses for the
imported conformance may be opaque---that is, they will never be
devirtualized to a particular implementation. However, they previously
would have referred to methods implemented in Objective-C anyway,
which are always dispatched with objc_msgSend. So this should have no
practical effect.
rdar://problem/32346184
Extend the check to make sure that the first type argument to an
imported Set or Dictionary type is Hashable actually checks
struct/enum types for Hashable conformances.
Fixes rdar://problem/30622665.
This breaks a cycle with a function in Foundation, but isn't a complete
fix: it will be similarly problematic if a function that can't have the
throws conversion is added.
This lets us serialize that decision, which means we can conceivably
/change/ the decision in later versions of the compiler without
breaking existing code. More immediately, it's groundwork that will
eventually allow us to drop decls from the AST without affecting
vtable layout.
This isn't actually a great answer; what we really want is for SIL
vtables to be serialized consistently and treated as the point of
truth. But that would be more change than we're comfortable taking in
the Swift 4 timeframe.
First part of rdar://problem/31878396.
This means all cross-module references and all mangled names will
consistently use the Swift 4 name (the canonical type), no special
handling required.
The main thing we lose here is that the Swift 4 names of imported
types become usable in Swift 3 mode without any diagnostics, similar
to how most language features introduced in Swift 4 are available in
Swift 3 mode. It also implies that the Swift 4 name will show up in
demangled names.
rdar://problem/31616162
- Add CompilerInvocation::getPCHHash
This will be used when creating a unique filename for a persistent
precompiled bridging header.
- Automatically generate and use a precompiled briding header
When we're given both -import-objc-header and -pch-output-dir
arguments, we will try to:
- Validate what we think the PCH filename should be for the bridging
header, based on the Swift PCH hash and the clang module hash.
- If we're successful, we'll just use it.
- If it's out of date or something else is wrong, we'll try to
emit it.
- This gives us a single filename which we can `stat` to check for the
validity of our code completion cache, which is keyed off of module
name, module filename, and module file age.
- Cache code completion results from imported modules
If we just have a single .PCH file imported, we can use that file as
part of the key used to cache declarations in a module. Because
multiple files can contribute to the __ObjC module, we've always given
it the phony filename "<imports>", which never exists, so `stat`-ing it
always fails and we never cache declarations in it.
This is extremely problematic for projects with huge bridging headers.
In the case where we have a single PCH import, this can bring warm code
completion times down to about 500ms from over 2-3s, so it can provide a
nice performance win for IDEs.
- Add a new test that performs two code-completion requests with a bridging header.
- Add some -pch-output-dir flags to existing SourceKit tests that import a bridging
header.
rdar://problem/31198982
We synthesize fake source locations for module imports that come from
Swift code; these locations have to be both valid and distinct for
Clang to use. We've mostly been getting away with simply making fake
offsets from the main file, but after the offsets start exceeding the
size of the buffer they start pointing into some /other/ file, and
then if Clang's SourceManager tries to order those locations it gets
/very/ confused.
This commit fixes that by allocating a 256K buffer of zeros and using
offsets into that instead. The hope is that a read-only mmap'd buffer
of zeros that never gets read (except possibly to look for newlines)
will be cheap to allocate.
(Why not just make the main file buffer 256K? Because we actually try
to parse that, and there's really no reason for the lexer to go crawl
through that file eagerly.)
This test case isn't the best because it doesn't actually fail in the
old code, but if only the assertion was added we at least hit that.
I did verify with the reproducing project I have that we no longer
hit this issue.
rdar://problem/30924269