ClangImporter can now import non-public members as of be73254cdc and 66c2e2c52b, but doing so triggers some latent ClangImporter bugs in projects that don't use or need those non-public members.
This patch introduces a new experimental feature flag, ImportNonPublicCxxMembers, that guards against the importation of non-public members while we iron out those latent issues. Adopters of the SWIFT_PRIVATE_FILEID feature introduced in bdf22948ce can enable this flag to opt into importing private members they wish to access from Swift.
rdar://145569473
This patch is follow-up work from #78942 and imports non-public members,
which were previously not being imported. Those members can be accessed
in a Swift file blessed by the SWIFT_PRIVATE_FILEID annotation.
As a consequence of this patch, we are also now importing inherited members
that are inaccessible from the derived classes, because they were declared
private, or because they were inherited via nested private inheritance. We
import them anyway but mark them unavailable, for better diagnostics and to
(somewhat) simplify the import logic for inheritance.
Because non-public base class members are now imported too, this patch
inflames an existing issue where a 'using' declaration on an inherited member
with a synthesized name (e.g., operators) produces duplicate members, leading
to miscompilation (resulting in a runtime crash). This was not previously noticed
because a 'using' declaration on a public inherited member is not usually
necessary, but is a common way to expose otherwise non-public members.
This patch puts in a workaround to prevent this from affecting the behavior
of MSVC's std::optional implementation, which uses this pattern of 'using'
a private inherited member. That will be fixed in a follow-up patch.
Follow-up work is also needed to correctly diagnose ambiguous overloads
in cases of multiple inheritance, and to account for virtual inheritance.
rdar://137764620
If a C++ `struct Base` declares a method with a Clang attribute that Swift is able to import, and `struct Derived` inherits from `Base`, the method should get cloned from `Base` to `Derived` with its attributes.
Previously we were only cloning one attribute at most due to a bug in `cloneImportedAttributes`. DeclAttributes is an intrusively linked list, and it was being made invalid while iterating over it: `otherDecl->getAttrs().add(attrs)` iterates over the list and calls `otherDecl->add(eachElement)`, which invalidates the iterator after the first iteration.
We do not synthesize the inheritance thunks correctly for such methods. Do not try to synthesize them, as that causes issues when there are two overloads of the same method, one with rvalue this and one without.
The proper solution is tracked as https://github.com/apple/swift/issues/69745
Unblocks rdar://114282353
Trying to use members of C++ private base classes from Swift causes an assertion failure in ClangImporter:
```
<build dir>/swift/lib/swift/macosx/arm64/libcxxshim.h:2:66: error: cannot cast 'A' to its private base class 'B'
To __swift_interopStaticCast(From from) { return static_cast<To>(from); }
^
```
Such members should not be exposed.
rdar://103871000
This commit adds very basic support for importing and calling base class methods, getting and setting base class fields, and using types inside of base classes.