This patch improves the warning for C++ APIs returning
`SWIFT_SHARED_REFERENCE` types but not annotated with either
`SWIFT_RETURNS_RETAINED` or `SWIFT_RETURNS_UNRETAINED` in the following
ways:
1. The warning for missing `SWIFT_RETURNS_(UN)RETAINED` annotations is
now emitted on Swift use sites, rather than while importing the API
(func/method decls).
- This logic is now implemented as a Misl Diagnostic in function
`diagnoseCxxFunctionCalls` in file lib/Sema/MiscDiagnostics.cpp.
- The warning is now triggered only when the API is actually used, which
reduces noise in large C++ headers.
- These warnings are still gated behind experimental-feature-flag `WarnUnannotatedReturnOfCxxFrt`
rdar://150800115
After #83289 and #82879 landed we should no longer get deserialization
failures and this feature is no longer behind a flag. This patch also
changes how we query if a function's return value depends on self.
Previously, we queried the lifetime dependencies from the Swift
declaration. Unfortunately, this is problematic as we might have not
finished fully importing the types in the function signature just yet
and the compiler might end up populating the conformance tables
prematurely. To work this around, I store functions with self-dependent
return values where lifetimes are computed in the importer for later
use.
The PR also adds a test to make sure the addressable dependency feature
will not result in deserialization errors.
rdar://155319311&154213694&112690482&128293252
AppKit defines certain constants in Objective-C, and then renames them into different constants in Swift, e.g. `NSUpArrowFunctionKey` is renamed into `NSEvent.SpecialKey.upArrow.rawValue`.
In addition to that, AppKit also re-defines these constants in pure-Swift, which isn't the intended mechanism for renaming such constants.
Prior to https://github.com/llvm/llvm-project/pull/145947, Clang was silently dropping the `SwiftName` API Notes attributes on these constants due to a bug in the name validation mechanism. Clients of AppKit relied on that behavior and continued to use the old spelling in Swift. To preserve source compatibility and avoid a deprecation error, let's continue dropping the `SwiftName` attribute on select constants from AppKit.
rdar://157485334
If a C++ struct is annotated with `__attribute__((swift_attr("~Copyable")))`, Swift should not try to instantiate the copy constructor of the struct. This provides an escape hatch for C++ types that are designed to be non-copyable, but do not explicitly define a deleted copy constructor, and instead trigger complex template instantiation failures when a copy is attempted.
rdar://157034491
A C struct can be imported as noncopyable, but C doesn't have
destructors, so there is no way to provide user-defined logic to
perform the destruction. Introduce a new swift_attr that applies to
imported noncopyable types and which provides such a "destroy"
operation. It can be used like this:
typedef struct __attribute__((swift_attr("~Copyable")))
__attribute__((swift_attr("destroy:wgpuAdapterInfoFreeMembers")))
WGPUAdapterInfo { /*...*/ } WGPUAdapterInfo;
void wgpuAdapterInfoFreeMembers(WGPUAdapterInfo adapterInfo);
This will bring the WGPUAdapterInfo struct in as a noncopyable type
that will be cleaned up by calling wgpuAdapterInfoFreeMembers once it
is no longer in use.
Implements rdar://156889370.
The code for handling Swift conforms_to attributes was specific to
C++ record types. Generalize it to work on typedefs imported as
nominal types, also in C.
Fixes rdar://156290361.
Normally, Swift cannot import an incomplete type. However, when we are
importing a SWIFT_SHARED_REFERENCE type, we're always dealing with
pointers to the type, and there is no need for the underlying type to
be complete. This permits a common pattern in C libraries where the
actual underlying storage is opaque and all APIs traffic in the
pointer, e.g.,
typedef struct MyTypeImpl *MyType;
void MyTypeRetain(MyType ptr);
void MyTypeRelease(MyType ptr);
to use SWIFT_SHARED_REFERENCE to import such types as foreign
references, rather than as OpaquePointer.
Fixes rdar://155970441.
This patch re-enables diagnostics for unannotated C++ functions or
methods returning `SWIFT_SHARED_REFERENCE` types. These warnings now
fire only **once per source location**, even in the presence of multiple
template instantiations. This avoids diagnostic duplication that was a
key source of noise in the compilation of larger codebases.
These warnings were previously disabled starting in **Swift 6.2** via
[PR-#81411](https://github.com/swiftlang/swift/pull/81411) due to
concerns around false positives and excessive duplication in projects
adopting C++ interop. This patch addresses the duplication issue by
adding source-location-based caching, which ensures that a warning is
emitted only once per source location, even across template
instantiations with different types.
However, the false positive issue remains to be investigated and will be
addressed in a follow-up patch. Until that happens, the warnings are
gated behind a new experimental feature flag:
`WarnUnannotatedReturnOfCxxFrt`. This feature will be enabled by default
only after thorough qualification and testing on large C++ codebases.
rdar://154261051
When importing custom availability domains with dynamic predicates from Clang
modules, synthesize predicate functions for `if #available` queries and call
them when generating SIL.
Resolves rdar://138441312.
When MemberImportVisibility is enabled we failed to find certain base
methods from the extensions when said base methods are imported from
C++.
rdar://154887575
Currently, when we jump-to-definition for decls that are macro-expanded
from Clang imported decls (e.g., safe overloads generated by
@_SwiftifyImport), setLocationInfo() emits a bongus location pointing to
a generated buffer, leading the IDE to try to jump to a file that does
not exist.
The root cause here is that setLocationInfo() calls getOriginalRange()
(earlier, getOriginalLocation()), which was not written to account for
such cases where a macro is generated from another generated buffer
whose kind is 'AttributeFromClang'.
This patch fixes setLocationInfo() with some refactoring:
- getOriginalRange() is inlined into setLocationInfo(), so that the
generated buffer-handling logic is localized to that function. This
includes how it handles buffers generated for ReplacedFunctionBody.
- getOriginalLocation() is used in a couple of other places that only
care about macros expanded from the same buffer (so other generated
buffers not not relevant). This "macro-chasing" logic is simplified
and moved from ModuleDecl::getOriginalRange() to a free-standing
function, getMacroUnexpandedRange() (there is no reason for it to be
a method of ModuleDecl).
- GeneratedSourceInfo now carries an extra ClangNode field, which is
populated by getClangSwiftAttrSourceFile() when constructing
a generated buffer for an 'AttributeFromClang'. This could probably
be union'ed with one or more of the other fields in the future.
rdar://151020332
Functions that are isolated to a global actor don't have completion
handlers imported as `@Sendable`. Main actor isolated functions with
completion handlers that are always called on the main actor is a
very common Objective-C pattern, and this carve out will eliminate
false positive warnings in the cases where the main actor annotation
is missing on the completion handler parameter.
Resolves: rdar://149811049
When instantiating templated functions with pointers to the templated
type, the ClangImporter does not strip type sugar. This strips type
sugar for bounds attributes, to make sure that they import the same
regardless of whether they are parsed or not.
rdar://151041990
This lifts the check for the feature flag up into the `importParameterType`
from `importType` and means that completion handler type for `async` variant
is no longer gains `@Sendable` attribute.
Unfortunately, there is no common abstraction for initializers and
functions in SwiftSyntax, so this PR rolls our own. Alternatively, we
could probably achieve something similar with a new protocol, but we
only needed a handful of fields so this change keeps it simple.
rdar://152112660
Implements SE-0460 -- the non-underscored version of @specialized.
It allows to specify "internal" (not abi affecting) specializations.
rdar://150033316
Also renames it to findOptionSetEnum() to make it a bit clearer at face
value that the returned ImportedType will contain a Swift enum.
Also refactors some nearby instances of
if (auto e = dyn_cast<ElaboratedType>(t))
t = e->desugar();
into a helper function, desugarIfElaborated().
Previously, `__attribute__((swift_attr("sending")))` would only be
resolved when attached to declarations. This patch expands it to be
a type attribute as well, which enables it to occur in the result and
parameter positions for blocks, function pointers, and lambdas.
Resolves rdar://148435359
Importing C++ class templates in symbolic mode has proven to be problematic in interaction with other compiler features, and it isn't used widely. This change removes the feature.
rdar://150528798
Apparently, clang will pick the source range of the canonical
declaration for template specializations. This might be in a different
buffer than the definition triggering various issues. Fortunately, Clang
also has the source locations we want, we just need to use a different
API to get them. Unfortunately, I haven't figured it out yet how to
trigger a failing test.
rdar://148250404
Building on top of PR #79288, this update synthesizes a static factory method using the default new operator, with a call to the default constructor expression for C++ foreign reference types, and imports them as Swift initializers.
rdar://147529406
When importing C++ decls in symbolic mode, class templates are not instantiated, which means they might not have a destructor or a move constructor. Make sure we are not trying to diagnose those missing lifetime operations in symbolic mode.
This fixes incorrect diagnostics that were emitted during indexing at the end of compilation:
```
warning: 'import_owned' Swift attribute ignored on type 'basic_string': type is not copyable or destructible
```
As a nice side effect, this moves the logic that emits these diagnostics from the request body, which might be invoked many times, to the importer itself, which is only invoked once per C++ class.
rdar://147421710
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
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.
Repeatedly lookup up a key from a dictionary can be justified whenever
the content of the dictionary might change between the lookups (so any
references into the dictionary might get invalidated). We had a couple
of instances where as far as I can tell no such modifications should
happen between two lookups with identical keys. This PR simplifies the
code to remove the extra lookups. It also removes a dictionary that was
completely unused.
This commit removes the guardrails in ImportDecl.cpp:SwiftDeclConverter
that prevent it from importing non-public C++ members. It also
accordingly adjusts all code that assumes generated Swift decls should
be public. This commit does not import non-public inherited members;
that needs its own follow-up patch.
Note that Swift enforces stricter invariants about access levels than C++.
For instance, public typealiases cannot be assigned private underlying types,
and public functions cannot take or return private types. Meanwhile,
both of these patterns are supported in C++, where exposing private types
from a class's public interface is considered feature. As far as I am aware,
Swift was already importing such private-containing public decls from C++
already, but I added a test suite, access inversion, that checks and
documents this scenario, to ensure that it doesn't trip any assertions.
A previous PR already added support to the SwiftifyImport macro to
generate safe wrappers. This PR makes ClangImporter emit the macro to do
the transformation.
This results in an automatic wrapper function with safe pointer types
when the imported function has bounds attributes. This exercises similar
pathways as the recently added functionality for specifying macros from
swift_attr. The new functionality is guarded by the experimental
language feature SafeInteropWrappers.
rdar://97942270
We only add conditional annotations because those do not break backward
compatibility (we might import span and similar view types as
non-escapable in the future). We inject these annotations in the
importer to make sure we have consistent behavior acress the different
standard library implementations. Once we can ship APINotes for the STL
and we have conditional escapability support in APINotes we can migrate
to that solution. But it is not possible as of today and Clang already
has precedent of injecting information for the STL with lifetimebound.
rdar://139065558
Since we can't do a proper "deep" clone of expression nodes, cloning
such a CustomAttr is necessarily shallow. In such cases, don't cache
the swift_attr source files at all, so we get fresh attribute nodes
for each such usage.
Unfortunately, importing them as is results in ambiguous call sites.
E.g., std::vector::push_back has overloads for lvalue reference and
rvalue reference and we have no way to distinguish them at the call site
in Swift. To overcome this issue, functions with rvalue reference
parameters are imported with 'consuming:' argument labels.
Note that, in general, move only types and consuming is not properly
supported in Swift yet. We do not invoke the dtor for the moved-from
objects. This is a preexisting problem that can be observed with move
only types before this PR, so the fix will be done in a separate PR.
Fortunately, for most types, the moved-from objects do not require
additional cleanups.
rdar://125816354