Commit Graph

2609 Commits

Author SHA1 Message Date
Doug Gregor
49febcd468 Merge pull request #83252 from DougGregor/import-conforms-to-newtype
[Clang importer] Handle Swift conformances on typedefs and C types
2025-07-23 15:38:01 -07:00
Doug Gregor
858383c71d Merge pull request #83173 from DougGregor/shared-reference-of-incomplete
[Clang importer] Import incomplete SWIFT_SHARED_REFERENCE types
2025-07-23 13:11:56 -07:00
Kuba (Brecka) Mracek
407ef9a302 Merge pull request #83238 from kubamracek/const-cgfloat-typedef
[ClangImporter] Skip importing values for CGFloat typedefs on top of CGFloats direct
2025-07-23 10:43:24 -07:00
Gábor Horváth
d7bdbcb1c0 Merge pull request #83231 from Xazax-hun/addressable-params-copy-revert
Revert [cxx-interop] Avoid copies when accessing pointee
2025-07-23 12:31:14 +01:00
Doug Gregor
c5db5cced5 [Clang importer] Handle Swift conformances on typedefs and C types
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.
2025-07-22 20:20:23 -07:00
Doug Gregor
72be0e0851 [Clang importer] Import incomplete SWIFT_SHARED_REFERENCE types
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.
2025-07-22 20:20:23 -07:00
Kuba Mracek
6ec280d4e1 [ClangImporter] Skip importing values for CGFloat typedefs on top of CGFloats direct 2025-07-22 10:10:15 -07:00
Gabor Horvath
db4b4c8abe Revert "Merge pull request #82480 from swiftlang/gaborh/addressable_params_copy"
Unfortunately, addressable parameters are viral, the whole dependency
chain needs to be consistent otherwise we get deserialization errors
when loading a module. The solution is to universally enable addressable
parameters for C++ interop but there are some blockers at the moment
that need to be solved first. Temporarily revert these changes until
those blockers are resolved.

This reverts commit b00ff4568b, reversing
changes made to 396379ecbf.
2025-07-22 14:03:24 +01:00
Anthony Latsis
2920ea84d1 Address llvm::(Mutable)ArrayRef ctor deprecations
See:
- https://github.com/llvm/llvm-project/pull/146113
- https://github.com/llvm/llvm-project/pull/146011
2025-07-21 12:36:53 +01:00
Susana Monteiro
0337f7e64a Merge pull request #83067 from susmonteiro/rename-virtual-methods
[cxx-interop] Adding swift_name attributes to virtual methods overrides
2025-07-18 11:57:46 +01:00
susmonteiro
585ca5e2da [cxx-interop] Adding swift_name attributes to virtual methods overrides 2025-07-17 16:23:32 +01:00
fahadnayyar
a4eeae2a01 [cxx-interop] Re-enable warnings for unannotated C++ APIs returning SWIFT_SHARED_REFERENCE types under an experimental feature flag (#82488)
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
2025-07-15 02:56:34 -07:00
Allan Shortlidge
3d722e1919 ClangImporter: Generate and call custom availability domain predicates.
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.
2025-07-10 08:15:01 -07:00
Egor Zhdan
569ca005e8 Merge pull request #82680 from swiftlang/egorzhdan/enable-c-frt
[cxx-interop] Enable foreign reference types in C interop
2025-07-07 19:42:06 +01:00
Egor Zhdan
a18db8f49f Merge pull request #82579 from swiftlang/egorzhdan/import-as-member-from-namespace
[cxx-interop] Allow import-as-member for functions declared within a namespace
2025-07-02 22:49:14 +01:00
Egor Zhdan
d3dc17a067 [cxx-interop] Allow import-as-member for functions declared within a namespace
This makes it possible to use trigger import-as-member for C++ functions declared within namespaces. Previously only functions declared at the file level were supported.

rdar://138930205
2025-07-02 16:40:40 +01:00
Egor Zhdan
9178af3ec7 [cxx-interop] Enable foreign reference types in C interop
Most of the logic for C++ foreign reference types can be applied to C types as well. Swift had a compiler flag `-Xfrontend -experimental-c-foreign-reference-types` for awhile now which enables foreign reference types without having to enable C++ interop. This change makes it the default behavior.

Since we don't expect anyone to pass `experimental-c-foreign-reference-types` currently, this also removes the frontend flag.

rdar://150308819
2025-07-01 18:46:22 +01:00
Egor Zhdan
d203591201 Merge pull request #82626 from swiftlang/egorzhdan/nfc-move-header
[cxx-interop] NFC: Move a header from `include` into `lib`
2025-06-30 20:40:04 +01:00
Henrik G. Olsson
e9ba8f8a03 Merge pull request #81855 from hnrklssn/swiftify-availability-check-sdk
[Swiftify] Adjust _SwiftifyImport invocation to align with the signature
2025-06-30 12:00:20 -07:00
Gábor Horváth
b00ff4568b Merge pull request #82480 from swiftlang/gaborh/addressable_params_copy
[cxx-interop] Avoid copies when accessing pointee
2025-06-30 17:41:39 +02:00
Egor Zhdan
0dd18ed427 [cxx-interop] NFC: Move a header from include into lib
CXXMethodBridging.h isn't supposed to be used outside of ClangImporter, so let's keep it inside of ClangImporter's implementation.
2025-06-30 15:58:00 +01:00
Henrik G. Olsson
1d1c64220c Don't attach @_SwiftifyImport if macro declaration not found 2025-06-27 21:37:41 -07:00
Henrik G. Olsson
bd11926bf7 [Swiftify] Adjust _SwiftifyImport invocation to align with the signature
of the macro in the currently laoded macro module

Stdlib macros are shipped with the SDK, so we need to make sure that the
way we invoke the macro matches the version of the macro in the SDK.
This patch skips the `spanAvailability` parameter if it isn't present.
There's no good way to test this, because we will always pick up the
current macro in our llvm-lit test suite, but I've tested it manually.

rdar://152278292
2025-06-27 19:10:23 -07:00
Henrik G. Olsson
374658aae0 [Swiftify] Don't import counted_by with suffixed integer literals (#82469)
Integer literal expressions with types that are not of type `int` are
printed with a suffix to indicate the type (e.g. `123U` or `456L` for
`unsigned` and `long`). This is not valid syntax for integer literals in
Swift, so until we fully translate the count expr syntax to Swift we
need to avoid importing these count expressions.

Also fixes some -Werror related stuff in test cases.

rdar://154141719
2025-06-27 09:27:50 -07:00
Gabor Horvath
7474a51691 [cxx-interop] Avoid copies when accessing pointee
Previously, we would get two copies, one accessing the pointee and one
when we pass the pointee as a method as the implicit self argument.
These copies are unsafe as they might introduce slicing. When
addressable paramaters features are enabled, we no longer make these
copies for the standard STL types. Custom smart pointers can replicate
this by making the lifetime dependency between the implicit object
parameter and the returned reference of operator* explicit via a
lifetime annotation.

rdar://154213694&128293252&112690482
2025-06-25 17:09:55 +01:00
Anthony Latsis
ad8c52237c Sema: Fix the insertion location for conformances attributes 2025-06-24 14:49:03 +01:00
John Hui
a0d3ad7bd0 Merge pull request #82006 from j-hui/jump-to-def-for-macro-expanded-clang-imports
[SourceKit] Support location info for macro-expanded Clang imports
2025-06-19 02:01:40 -07:00
John Hui
44aba1382d [SourceKit] Support location info for macro-expanded Clang imports
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
2025-06-12 18:22:06 -07:00
Slava Pestov
71186eb07f AST: Call setExtendedNominal() instead of cacheOutput(ExtendedNominalRequest...) 2025-06-11 20:07:42 -04:00
Gábor Horváth
296726aa12 Merge pull request #82016 from swiftlang/gaborh/swiftify-private
[cxx-interop] Avoid swiftifying private and protected methods
2025-06-06 17:19:46 +01:00
Gabor Horvath
6eb7057e75 [cxx-interop] Avoid swiftifying private and protected methods
The generated overloads do not get seralized and later on the compiler
crashes due to the missing body of the SILFunction. This PR works this
problem around by not generating these overloads. We plan to address the
serialization issue later.

rdar://152181531
2025-06-06 11:07:01 +01:00
Gabor Horvath
868c85d5f0 [cxx-interop] Only swiftify template instantiations behind type aliases
While I could not trigger a scenario where the generated macro triggers
a compilation error, the generated code is definitely not valid Swift.

rdar://151422108
2025-06-06 10:31:52 +01:00
Henrik G. Olsson
89b09a69e4 Merge pull request #81752 from hnrklssn/swiftify-sized-sizedby
[Swiftify] Support __sized_by on byte-sized pointee types
2025-06-05 08:42:42 -07:00
Henrik G. Olsson
114a1a924c address review comments 2025-06-04 11:26:15 -07:00
Gabor Horvath
d5faddaa9b [cxx-interop] Support Swiftifying C++ constructors
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
2025-06-04 10:06:16 +01:00
Henrik G. Olsson
0f0a2ca4bb [Swiftify] Support __sized_by on byte-sized pointee types
Previously we would emit a macro that would error on expansion when
trying to add a safe wrapper to a function with __sized_by on a type
that mapped to UnsafePointer<T> instead of UnsafeRawPointer or
OpaquePointer. __sized_by is acceptable when used on byte-sized pointee
types, so this adds machinery in the macro expansion to support that.
Meanwhile on the ClangImporter side, we add a check so that __sized_by
on pointee types with a size is ignored if that size is larger than 1
byte.

When _SwiftifyImport applies .sizedBy to a pointer of type
UnsafePointer<T> it will still map it to a
RawSpan/UnsafeRawBufferPointer in the safe overload. The assumption is
that any API using __sized_by is dealing with raw bytes, so raw pointers
are a better Swift abstraction than UnsafePointer<CChar> etc. It also
lets the user avoid doing a scary pointer cast from some potentially
larger-than-byte-sized pointer to a byte-sized pointer. Casts to
RawPointers are generally safer and more ergonomic.

rdar://150966684
rdar://150966021
2025-05-29 13:32:53 -07:00
Henrik G. Olsson
262a53f599 [Swiftify] Update availability for CxxSpan<->Span, fix lifetimebound on parameters with reference type (#81634)
Update availability for CxxSpan<->Span, fix lifetimebound on parameters
with reference type

Because swift-ide-test doesn't care about typechecking,
std-span-interface.swift passed despite containing 2 separate errors.
This updates the test file to properly exercise the entire compilation
pipeline for the macro expansions, by running swift-frontend
-emit-module and calling each macro expansion.

The first issue was that CxxSpan initializers taking [Mutable]Span still
had their availability set to Swift 6.2+, even after back-deploying
caused [Mutable]Span to have availability back to Swift 5.0. Since
_SwiftifyImport expansions copy the availbility of Span, this resulted
in the macro expansions calling unavailable initializers. Interestingly
enough, this manifested itself in the form of a tripped assert in SIL
verification, because although we do now typecheck the expansions from
_SwiftifyImport, the compilation can still keep going after
`shouldEmitFunctionBody` returns false: the macro expansion declaration
is still there, but is now missing its definition, despite not being
external.

The second issue was when parameters with C++ reference types were
annotated with `[[clang::lifetimebound]]`. For parameters with a type
that is `Escapable`, this is normally done using `@lifetime(borrow
foo)`. However C++ reference parameters are imported as `inout`, which
requires the `@lifetime(&foo)` syntax.

rdar://151493400
rdar://151678415
2025-05-22 15:36:19 -07:00
John Hui
828876f4ec Merge pull request #81625 from j-hui/fix-unavailable-enum 2025-05-22 00:01:30 -07:00
Henrik G. Olsson
6534b9b14f [Swiftify] Copy doc comment from clang node (#81584)
Swift nodes imported from clang don't have doc comments carried over,
but IDEs are clever enough to fetch the comments from the associated
clang node. The swift node in the macro expansion from _SwiftifyImport
doesn't have a clang node directly associated with it however.

This patch adds the same comment from the clang node to the
_SwiftifyImport macro invocation node. Since the macro has access to
this node, it can easily copy over its leading trivia.

For now the comment is not altered at all, meaning @param still remains
even if the parmeter is removed.

rdar://151346977
2025-05-20 08:06:20 -07:00
John Hui
5aa5bcfea2 [NFC] [cxx-interop] Flatten findOptionSetEnum() and move it to ImportEnumInfo.cpp
It's at home there alongside other ObjC enum-specific logic, rather than
in the middle of ImportDecl.cpp (since it isn't directly or exclusively
related to importing decls).
2025-05-19 14:21:49 -07:00
John Hui
c7070e73fe [NFC] [cxx-interop] Consolidate uses of findOptionSetType() helper function
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().
2025-05-19 14:10:49 -07:00
Hamish Knight
edca7c85ad Adopt ABORT throughout the compiler
Convert a bunch of places where we're dumping to stderr and calling
`abort` over to using `ABORT` such that the message gets printed to
the pretty stack trace. This ensures it gets picked up by
CrashReporter.
2025-05-19 20:55:01 +01:00
Henrik G. Olsson
e1eb960e7f [Swiftify] Don't create safe wrapper for autoreleasing pointers (#81568)
_SwiftifyImport doesn't know how to handle
AutoreleasingUnsafeMutablePointer, so we should not attach any
.countedBy information for pointers that are imported as this type.

This also adds defensive checks against adding .countedBy to any pointer
type that _SwiftifyImport doesn't know how to transform.

rdar://151479521
2025-05-17 20:33:00 -07:00
Kuba Mracek
1ecdb17fcc [ClangImporter] Fix enum conversion type when importing global values (unwrap if needed) 2025-05-13 16:02:15 -07:00
fahadnayyar
49aea31e41 [cxx-interop] Disabling should be annotated with SWIFT_RETURNS_(UN)RETAINED warning (#81411)
In Swift 6.1, we introduced warnings for C++ APIs returning
SWIFT_SHARED_REFERENCE types that lack the SWIFT_RETURNS_(UN)RETAINED
annotations. These warnings serve as a reminder to annotate APIs, as the
absence of these annotations can lead to arbitrary assumptions about the
ownership of returned SWIFT_SHARED_REFERENCE values. This could result
in both use-after-free (memory safety) bugs and memory leaks.

We have received feedback from a few adopters indicating potential false
positive cases where these warnings are triggered. Consequently, we have
decided to disable these warnings in Swift 6.2 and re-qualify the
warnings on larger projects to ensure their effectiveness and eliminate
false positives. Our intention is to re-enable the warnings in later
beta releases of Swift 6.2 once we have stronger evidence of their
effectiveness on large codebases and proof that there are no false
positives.

rdar://150937617
rdar://150800115
2025-05-09 17:36:00 -07:00
John Hui
203acbbb47 [NFC] Tidy up formatting for CountedByExpressionValidator
(Renamed from CATExprValidator)
2025-05-09 00:25:20 -07:00
John Hui
e5b1f4a251 [Swiftify] Do not swiftify non-Swift-like counted_by exprs
__counted_by (and __sized_by) expressions can have arbitrary C syntax
in them, such as:

    void foo(int * __counted_by(*len) p, int *len);

When @_SwififyImport tries to generate Swift code for this, the
expression `*len` leads to a syntax error, since it isn't valid Swift.

This patch adds a check to ensure we only attach the Swiftify macro to
__counted_by expressions that are also syntactically valid in Swift.

rdar://150956352
2025-05-08 21:13:20 -07:00
Henrik G. Olsson
59d7d3160f [Swiftify] Emit @availability when expansions contain Span (#81320)
This prevents errors when compiling for older targets using a newer
compiler.

rdar://150740330
2025-05-08 16:13:24 -07:00
fahadnayyar
b311c63ea9 [cxx-interop] Remove SWIFT_RETURNED_AS_RETAINED_BY_DEFAULT annotation (#81329)
This patch removes the `SWIFT_RETURNED_AS_RETAINED_BY_DEFAULT`
annotation while maintaining the support for
`SWIFT_RETURNED_AS_UNRETAINED_BY_DEFAULT`. These type-level annotations
were initially introduced in
[PR-81093](https://github.com/swiftlang/swift/pull/81093) to reduce the
annotation burden in large C++ codebases where many C++ APIs returning
`SWIFT_SHARED_REFERENCE` types are exposed to Swift.

### Motivation
The original goal was to make C++ interop more ergonomic by allowing
type-level defaults for ownership conventions
for`SWIFT_SHARED_REFERENCE` types . However, defaulting to retained
return values (+1) seems to be problematic and poses memory safety
risks.

### Why we’re removing `SWIFT_RETURNED_AS_RETAINED_BY_DEFAULT`

- **Memory safety risks:** Defaulting to retained can potentially lead
to use-after-free bugs when the API implementation actually returns
`unowned` (`+0`). These errors are subtle and can be hard to debug or
discover, particularly in the absence of explicit API-level
`SWIFT_RETURNS_(UN)RETAINED` annotations.
- **Risky transitive behavior:** If a `SWIFT_SHARED_REFERENCE` type is
annotated with `SWIFT_RETURNED_AS_RETAINED_BY_DEFAULT`, any new C++ API
returning this type will inherit the retained behavior by default—even
if the API's actual return behavior is unretained. Unless explicitly
overridden with `SWIFT_RETURNS_UNRETAINED`, this can introduce a silent
mismatch in ownership expectations and lead to use-after-free bugs. This
is especially risky in large or evolving codebases where such defaults
may be overlooked.
- **Simpler multiple inheritance semantics:** With only one type-level
default (`SWIFT_RETURNED_AS_UNRETAINED_BY_DEFAULT`), we avoid
complications that can arise when multiple base classes specify
conflicting ownership defaults. This simplifies reasoning about behavior
in class hierarchies and avoids ambiguity when Swift determines the
ownership convention for inherited APIs.

### Why we’re keeping `SWIFT_RETURNED_AS_UNRETAINED_BY_DEFAULT`
- It still enables projects to suppress warnings for unannotated C++
APIs returning `SWIFT_SHARED_REFERENCE` types, helping to reduce noise
while maintaining clarity.
- It encourages explicitness for retained behavior. Developers must
annotate retained return values with `SWIFT_RETURNS_RETAINED`, making
ownership intent clearer and safer.
- The worst-case outcome of assuming unretained when the return is
actually retained is a memory leak, which is more tolerable and easier
to debug than a use-after-free.
- Having a single default mechanism improves clarity for documentation,
diagnostics, and long-term maintenance of Swift/C++ interop code.
2025-05-07 13:25:25 -07:00
Egor Zhdan
294e4cf21b Merge pull request #81257 from swiftlang/egorzhdan/remove-symbolic-mode
[cxx-interop] Remove symbolic import mode
2025-05-05 18:36:32 +01:00