ClangImporter has logic that infers default arguments of certain C/C++ types, such as the types declared via `CF_OPTIONS`/`NS_OPTIONS` macros.
There were some workarounds in place which triggered for C++ interop mode specifically. The workarounds were applying a heuristic based on the name of the type, which tried to match the behavior to non-C++ interop mode for certain types from the OS SDK. That was not working well for user-defined types, causing source compatibility breakages when enabling C++ interop.
This change replaces the name-based heuristic with a more robust criteria.
See also 3791ccb6.
rdar://142961112
This removes a workaround from the module interface loader, which was forcing AppKit and UIKit to be rebuilt from their textual interfaces with C++ interop disabled, even if the current compilation explicitly enables it.
The workaround was previously put in place because of a compiler error:
```
error: type 'AttributeScopes.AppKitAttributes.StrikethroughStyleAttribute' does not conform to protocol 'AttributedStringKey'
note: possibly intended match 'AttributeScopes.AppKitAttributes.StrikethroughStyleAttribute.Value' (aka 'NSUnderlineStyle') does not conform to 'Hashable'
```
`NSUnderlineStyle` is a C/C++ type from AppKit that is declared using `NS_OPTIONS` macro. `NS_OPTIONS`/`CF_OPTIONS` macros have different expansions in C vs C++ language modes. The C++ expansions weren't handled correctly by ClangImporter, resulting in two distinct Swift types being created: a `typealias NSUnderlineStyle` which was marked as unavailable in Swift, and `enum NSUnderlineStyle`. This mostly worked fine, since the lookup logic was picking the enum during regular name lookup. However, this silently broke down when rebuilding the explicit conformance from `AppKit.swiftinterface`:
```
extension AppKit.NSUnderlineStyle : Swift.Hashable {}
```
Swift was picking the (unavailable) typealias when rebuilding this extension, which means the (available) enum wasn't getting the conformance.
This is verified by an existing test (`test/Interop/Cxx/objc-correctness/appkit-uikit.swift`).
rdar://142961112
Importing these annotations were behind the LifetimeDependence
experimental flag. However, this feature flag is intended to guard the
use of @lifetime annotations on the Swift side and lifetime inference.
The checking of imported lifetime contracts should work even when this
flag is off. Removing the flag from the importer caused some fallout.
This was mostly due to calling getInterfaceType functions before the
import of some Swift declarations were fully done so the code was
slightly improved to make decisions only based on the C++ types.
There was also a crash when on-member functions imported as methods into
Swift. That is worked around in this PR.
There is one last feature check that we cannot remove yet, we generate
@lifetime annotations in the SwiftifyImport macro.
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
Unfortunately, Unsafe*Pointer types do not support non-escapable
pointees so we do not really have anything to map these types to at the
moment. Previously, importing such code resulted in crashes.
rdar://145800679
In C++, we always expected to invoke the dtor for moved-from objects.
This is not the case for swift. Fortunately, @inCxx calling convention
is already expressing that the caller supposed to destroy the object.
This fixes the missing dtor calls when calling C++ functions taking
rvalue references. Fixes#77894.
rdar://140786022
This PR adds a feature to import static factory functions returning
foreign reference types to be imported as initializers using the
SWIFT_NAME annotation.
This patch changes the class template printer to disambiguate const-qualified template arguments by wrapping them with __cxxConst<>, rather than suffixing them with _const.
This is necessary to accommodate template arguments that aren't just identifiers (i.e., Foo<Int_const> is ok, but Foo<Bar<T>_const> and Foo<((Bar) -> Baz)_const> are not syntactically valid). With this patch, we would produce Foo<__cxxConst<Int>>, Foo<__cxxConst<Bar<T>>, and Foo<__cxxConst<((Bar) -> Baz)>> instead.
This patch also disambiguates volatile-qualified template arguments with __cxxVolatile<>, and changes the printing scheme for std::nullptr_t from nil to __cxxNullPtrT (since nil is not a syntactically valid type name).
rdar://143769901
It turns out the query to check the reference semantics of a type had
the side effect of importing some functions/types. This could introduce
circular reference errors with our queries. This PR removes this side
effect from the query and updates the test files. Since we do the same
work later on in another query, the main change is just the wording of
the diagnostics (and we now can also infer immortal references based on
the base types). This PR also reorders some operations, specifically now
we mark base classes as imported before we attempt to import template
arguments.
After these changes it is possible to remove the last feature check for
strict memory safe mode. We want to mark types as @unsafe in both
language modes so we can diagnose redundant unsafe markers even when the
feature is off.
With the acceptance of SE-0458, allow the use of unsafe expressions, the
@safe and @unsafe attributes, and the `unsafe` effect on the for..in loop
in all Swift code.
Introduce the `-strict-memory-safety` flag detailed in the proposal to
enable strict memory safety checking. This enables a new class of
feature, an optional feature (that is *not* upcoming or experimental),
and which can be detected via `hasFeature(StrictMemorySafety)`.
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
The backtracing code will warn you if you attempt to forcibly enable
backtracing for a privileged executable. This is apparently upsetting
the Driver/filelists.swift test.
Since we want to force it on for tests, so that we will definitely get
backtraces, add an option to suppress warning messages, and turn that
on for tests as well.
rdar://144497613
__counted_by return values with .lifetimeDependence are now mapped to
Span instead of UnsafeBufferPointer. Also fixes bug where std::span
return values would map to Span even if lifetime dependence info was
missing.
This allows combining __counted_by and std::span for safe interop.
Previously we disabled this in C++ mode due to issues when bounds
attributes occurred directly or indirectly in templated contexts, but
this has now been resolved on the clang side.
importBoundsAttributes and importSpanAttributes are merged into a single
function named swiftify. This allows us to not have to duplicate the
effort of attaching _SwiftifyImport macros, but is also necessary to
allow importing a function with both __counted_by and std::span types.
This patch introduces an a C++ class annotation, SWIFT_PRIVATE_FILEID,
which will specify where Swift extensions of that class will be allowed
to access its non-public members, e.g.:
class SWIFT_PRIVATE_FILEID("MyModule/MyFile.swift") Foo { ... };
The goal of this feature is to help C++ developers incrementally migrate
the implementation of their C++ classes to Swift, without breaking
encapsulation and indiscriminately exposing those classes' private and
protected fields.
As an implementation detail of this feature, this patch introduces an
abstraction for file ID strings, FileIDStr, which represent a parsed pair
of module name/file name.
rdar://137764620
After PR #79424 was merged the compiler proper is doing inference on
what C++ types should be considered unsafe. Remove the duplicated (and
slightly divergent) logic from the importer as we no longer need it and
we should have a consistent view of what is considered unsafe. The only
divergence left is the old logic that renames some methods to have
"Unsafe" in their names. In the future, we want to get rid of this
behavior (potentially under a new interop version).
SafeInterop was guarding whether we import certain foreign types as
unsafe. Since these attrbutes are only considered when an opt-in strict
language mode is on, this PR removes this feature flag. We still rely on
the presence of the AllowUnsafeAttribute flag to add the unsafe
attributes to the imported types and functions.
PrintAsClang is supposed to emit declarations in the same order regardless of the compiler’s internal state, but we have repeatedly found that our current criteria are inadequate, resulting in non-functionality-affecting changes to generated header content. Add a diagnostic that’s emitted when this happens soliciting a bug report.
Since there *should* be no cases where the compiler fails to order declarations, this diagnostic is never actually emitted. Instead, we test this change by enabling `-verify` on nearly all PrintAsClang tests to make sure they are unaffected.
This did demonstrate a missing criterion that only mattered in C++ mode: extensions that varied only in their generic signature were not sorted stably. Add a sort criterion for this.
Usage of Span was temporarily behind an experimental feature flag. Now
that SE-0447 has been accepted, remove the experimental feature flag and
allow Span usage everywhere.
Implements rdar://144819992.
Unfortunately, this was not discovered earlier as swift-ide-test is not
invoking the SIL passes that produce this diagnostic. When creating
Swift spans from C++ spans we have no lifetime dependency information to
propagate as C++ spans are modeled as escapable types. Hence, this PR
introduces a helper function to bypass the lifetime checks triggered by
this discepancy. Hopefully, the new utility will go away as the lifetime
analysis matures on the Swift side and we get standardized way to deal
with unsafe lifetimes.
C++ code can return values that depend on the storage that backs the
references that were passed in as argument. Thus, swift should not
introdue temporary copies of that storage before invoking those
functions as they could result in lifetime issues.