This imports const members of C++ structs/classes stored properties with
an inaccessible setter.
Note that in C++ there are ways to change the values of const members,
so we don't use `WriteImplKind::Immutable` storage.
Resolves: [SR-12463](https://bugs.swift.org/browse/SR-12463)
* Don't import C++ class members that are protected or private.
We omit protected members in addition to private members because Swift
structs can't inherit from C++ classes, so there's effectively no way to
access them.
* Check access specifiers centrally in importDeclImpl().
* Fix macOS build by using <stddef.h> instead of <cstddef>.
Apparently, the macOS toolchain doesn't provide <cstddef>.
<stddef.h> is used in test/Inputs/clang-importer-sdk/usr/include/macros.h,
so I'm assuming it will be OK. (I don't unfortunately have a macOS
machine to test on.)
* Add comment explaining why we skip private and protected C++ class
members.
Non-identifier names aren't currently an issue, but it will become one
when we add more support for C++, e.g. for C++ constructors (which I
plan to tackle soon).
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
This comes up when an imported error enum has duplicate cases.
The FooError.Code enum has an alias for the duplicate case, and
the wrapper type FooError defines aliases for every member of
FooError.Code.
The implementation of importEnumCaseAlias() assumed that 'original'
was an EnumElementDecl, and built AST accordingly; however if it
is a 'VarDecl', we have to build a MemberRefExpr instead.
This regression was introduced in https://github.com/apple/swift/pull/25009.
Fixes <rdar://problem/58552618>.
Add an algorithm to go search the override tables *and* the existing
loaded members of a class for a redeclaration point. The idea is that
both mirrored protocol members and categories offer a way to convince
the Clang Importer to import a property twice. We support a limited form
of this multiple-imports behavior today by allowing the redeclared
property to refine a readonly property into a readwrite property.
To maintain both the refinement behavior and to disambiguate any
remaining cases of ambiguity caused by extensions, attempt to identify
a redeclaration point if we can't identify an override point. Then,
decline to import the redeclared member if we're successful.
Note that the algorithm as presented is subject to import ordering. That
is, if a framework declares both an overlay and a clang module unit, if
the overlay is not loaded or members from the overlay are not installed
in the class by the time we see the declaration we may fail to identify
an redeclaration point.
The regression tests are for rdar://59044692, rdar://59075988, and
rdar://59125907.
Once lazy loading supports mirrored protocol members, we can end up
calling importSubscript() for a setter method before we've mirrored
the getter. In this case, we call findCounterpart() with the setter,
which finds the imported getter from the ProtocolDecl itself.
Stop processing the potential subscript in this case, since when we
later mirror the protocol member, we'll go and build it again.
This should be NFC without the next change I'm working on.
Soft revert a09382c. It should now be safe to add this flag back as an optimization to specifically disable lazy member loading instead of all extension loading.
Push the flag back everywhere it was needed, but also push it into lookup for associated type members which will never appear in extensions.
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.
Allow two methods to be imported with the same selector, as long as they
have different Swift DeclNames. This is required for lazy mirrored protocol
member loading to work correctly, so that the same declarations are
imported regardless of name lookup order. The commit for the mirrored
protocol member change will have test cases that cover this behavior.
The Clang Importer allows for the creation of otherwise illegal Swift
ASTs because it does not run redeclaration checking or override
checking. These behaviors are also not a part of our test suite.
Correct the first issue by re-instating the old emergent behavior of
member loading occurring at all points in the class hierarchy before
a (lazy) lookup.
Correct the second issue by adding a regression test for a common
failure mode in the post-re-entrant-lookup Clang Importer.
We cannot stop accepting these cases, but a future compiler will warn
about them.
Attacks rdar://58493370
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.
Lazy member loading had an antagonistic relationship with the import-as-member facilities. The member tables were stored in a hash map that is keyed by serialized declaration context. While this was good for importing the entire member set of a given extension, it's in the complete wrong order for lazy member loading, which wants the same data keyed by base name.
Given that it is annoying to redo the globals-as-member tables to support one use case or the other, coupled with the fact that optimizing for one use-case automatically pessimizes the other, just take a page from rdar://18696086 and store the same information twice in two separate formats each optimized for the task at hand.
Preliminary benchmarks indicate that this leads to a 5% reduction in Clang-Imported entities which will drastically speed up most apps that use Dispatch and CoreGraphics.
We’re going to start serializing this for public types that have non-public-or-@usableFromInline initializers, so turn it into a request that we can query and cache it in the existing bit.
This serves as a bug fix and a nice cleanup. The old algorithm failed
to stop at the nearest override point and thereby introduced semantic
ambiguities on lookups for clashing overridden decls.
Resolves rdar://57916229
When deserializing a the (named) members of a class hierarchy, we
needn't walk all the way up the hierarchy, just into our superclass.
This will, in turn, walk to its superclass, etc. This is as opposed to
this work being repeated at each level of the recursive hierarchy.
Should be a small perf win over the last patch.
An unfortunate pessimization that is needed in order to properly build the member table to run override checking. Considering this was happening anyways thanks to re-entrant lookups, there shouldn't actually be a perf hit here.
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.
Prevents a cycle where a general access to all top level decls lead the
deserialization to call ClangImporter which triggered more
deserialization. It crashed the compiler in a complex case so only
limiting what is deserialized should be enough to fix this for now.
rdar://problem/57118844
These include memberwise initializers for pointer properties and enum
case constructors for pointer payloads. In both cases, the pointer is
being immediately escaped, so don't allow the user to pass a temporary
pointer value.
Christopher Rogers' (good) work in 49fd5acbb2 caught places where
the Swift compiler was allowing a @class to resolve to a Swift class
even if that class had a conflicting Objective-C name, or wasn't
intended to be exposed to Objective-C at all. Unfortunately, this
broke source compatibility in projects where people were relying on
this. Restore that functionality, but only as a fallback; matching the
Objective-C name is better than matching the Swift name.
rdar://problem/56681046
Previously we only did this for factory methods, but there's no reason
why we can't do it for regular init methods too, and doing so
simplifies the signature of SwiftDeclConverter::importConstructor.
Also remove some indirection through helper functions in ClangAdapter.
These were more useful back when Swift looked directly at API notes
instead of relying on Clang turning them into attributes; now they're
just an extra hop for no reason.
The code does naive lookup of Swift types using the type name, but sometimes the Swift type we're looking for only has that name in its @objc attribute. This change makes the compiler exclude certain Swift declarations from matching even if the Swift name is the same (namely, not being available in Obj-C or having a mismatched `@objc` name) and continue to find the correct declaration without using lookup by name.
Fixes SR-4827
This is an amalgam of simplifications to the way VarDecls are checked
and assigned interface types.
First, remove TypeCheckPattern's ability to assign the interface and
contextual types for a given var decl. Instead, replace it with the
notion of a "naming pattern". This is the pattern that semantically
binds a given VarDecl into scope, and whose type will be used to compute
the interface type. Note that not all VarDecls have a naming pattern
because they may not be canonical.
Second, remove VarDecl's separate contextual type member, and force the
contextual type to be computed the way it always was: by mapping the
interface type into the parent decl context.
Third, introduce a catch-all diagnostic to properly handle the change in
the way that circularity checking occurs. This is also motivated by
TypeCheckPattern not being principled about which parts of the AST it
chooses to invalidate, especially the parent pattern and naming patterns
for a given VarDecl. Once VarDecls are invalidated along with their
parent patterns, a large amount of this diagnostic churn can disappear.
Unfortunately, if this isn't here, we will fail to catch a number of
obviously circular cases and fail to emit a diagnostic.