Commit Graph

237 Commits

Author SHA1 Message Date
John Hui e68687d9e8 Merge pull request #88909 from j-hui/op-bool 2026-05-13 08:31:51 -07:00
John Hui 9c35230739 [cxx-interop] Synthesize __convertToBool() on-demand
Previously, we would import operator bool() by simply renaming it to
__convertToBool() using NameImporter. When we had a struct with that
member, we would conform it to CxxConvertibleToBool, which would allow
Swift.Bool to be initialized via Bool(fromCxx:).

However, this conformance relies on importing operator bool() eagerly,
and didn't work reliably when operator bool() was inherited. (Part of
the reason is because our base method synthesis logic would only create
clang::CXXMethodDecls but logic elsewhere specifically expected a
clang::CXXConversionDecl.) We also weren't handling things like
const-ness etc. directly.

This patch instead synthesizes a shim method __convertToBool() that
calls the underlying operator bool() const, which we no longer import
directly. It follows the same "look up and import on demand" pattern as
other special synthesized members that wrap operators, like .pointee and
.successor() and .subscript.

rdar://170857484
2026-05-12 17:29:12 -07:00
Gabor Horvath 0da3b379db [cxx-interop] Fix some clang tidy warnings
* Make some methods const or static
* Other minor cleanups
2026-03-26 14:48:24 +00:00
Gabor Horvath 75dc9b0283 [cxx-interop] More cleaups, no functional change intended
* Simplify some patterns (isa + cast)
* Add some consts
* Get rid of some temporary objects by constructing more objects in
  place
* Remove some duplicated lookups
* Other minor cleanups
2026-02-28 23:43:22 +00:00
Gabor Horvath 76e1f71674 [cxx-interop] Various code cleanups, no functional change intended
* Simplify conditionals
* Simplify loops
* Use llvm:: algorithms
* Simplify use of isa
* Deduplicate some code
* Other minor simplifications
2026-02-28 10:57:25 +00:00
Egor Zhdan 2c4e37fb31 [cxx-interop] Methods that return references to FRT are safe
If a C++ method returns a foreign reference type as a pointer (`MyImmortal*`), Swift correctly treats the method as safe. However, if the method returns a foreign reference type as a reference (`MyImmortal&`), Swift assumed that the method is unsafe.

This change adjusts the heuristic to treat such methods as safe. It also addresses a FIXME comment: previously, if the returned foreign reference type has inherited its `import_reference` attribute from a base class, the safety heuristic did not correctly detect the type as an FRT.

rdar://168057355
2026-01-27 16:54:44 +00:00
Gabor Horvath 86808a0cb4 Minor cleanups. 2026-01-21 12:09:37 +00:00
Gabor Horvath 8e8e5c4aae [cxx-interop] Support rvalue-ref qualified methods
We already imported methods that have && as qualifiers but did not
support them properly. When in the C++ code there is overloading based
on the reference qualifiers the imported Swift functions are ambiguous.
This patch append "Consuming" to the && qualified methods' names to
avoid the ambiguity. It also makes sure these methods are actually
imported as consuming.

In case of operators, however, Swift does not have a way to distinguish
between the consuming and non-consuming self. This patch prevents
importing the consuming variants. This fixes some compiler crashes
during deserialization that we hit due to the ambiguities.

Fixes #83801

rdar://158675235
2026-01-21 12:09:05 +00:00
Egor Zhdan 75c7610edb [cxx-interop] Do not import C++23 deducing this
We don't currently support C++23 deducing this parameters. Until we do, let's not expose incorrect function signatures to Swift.

rdar://161345481
2025-09-26 16:11:15 +01:00
Egor Zhdan 582357bf76 [cxx-interop] Import tilde operators
This teaches ClangImporter to import the bitwise not operator (`~`).

rdar://158366946 / resolves https://github.com/swiftlang/swift/issues/83740
2025-08-15 18:06:36 +01:00
Egor Zhdan 37c418275c [cxx-interop] Allow old spelling of AppKit constants
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
2025-08-06 16:28:15 +01:00
susmonteiro 585ca5e2da [cxx-interop] Adding swift_name attributes to virtual methods overrides 2025-07-17 16:23:32 +01:00
susmonteiro b3e228845b [cxx-interop] Allow virtual methods to be renamed with swift_name 2025-07-02 16:09:02 +01:00
John Hui 89f8855ad6 [cxx-interop] Check for NS_OPTIONS macro in findOptionSetEnum()
importer::findOptionSetEnum() uses some fragile heuristics to determine
whether a typedef is involved in the construction of a CF_OPTIONS or
NS_OPTIONS type. This patch adds an explicit check that the typedef is
expanded from either of those macros, to prevent, e.g., an unavailable
NS_ENUM, from being mistakenly recognized as an NS_OPTIONS.

Note that doing this is still kind of fragile, and prevents users from
building {NS,CF}_OPTIONS with their own macros. The right thing to do is
probably specifically look for the flag_enum attribute, but that is not
currently what we're doing for reasons whose discovery is left as
an exercise to the future git archaeologist.

This patch also removes (part of) a test case that builds
a CF_OPTIONS-like type with the "SOME_OPTIONS" macro, which is no longer
supported as of this patch.

rdar://150399978
2025-05-21 15:01:09 -07:00
Egor Zhdan b51cfa5c76 [cxx-interop] Remove symbolic import mode
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
2025-05-02 18:43:09 +01:00
Egor Zhdan eb7adc794d [cxx-interop] Do not import arithmetic operators with rvalue reference parameters
Currently those operators are imported with a `consuming:` label, which isn't valid in Swift.

We could just remove the label from these parameters, but that introduces a source breakage due to name lookup ambiguity.

So, to avoid ambiguity, let's not import such operators into Swift.

rdar://149020099
2025-04-11 17:07:37 +01:00
John Hui 50f5221962 [NFC] promote getOperatorName() to a non-static function (#80466) 2025-04-03 10:42:37 -04:00
Egor Zhdan 5b7c595b2e [cxx-interop] Remove workarounds for CF_OPTIONS default arguments
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
2025-03-11 12:47:21 +00:00
Egor Zhdan 3791ccb6e6 [cxx-interop] Allow AppKit & UIKit to be rebuilt with C++ interop enabled
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
2025-03-07 13:27:11 +00:00
Becca Royal-Gordon d8c8f6577b Merge pull request #79206 from beccadax/this-name-is-not-constructive
Diagnose and forbid invalid Swift names on inits
2025-02-17 20:17:56 -08:00
Gabor Horvath 410341671e [SE-0458] Unify escapibility inference for AST and Interop
Interop is injecting escapability annotations for the STL and doing a
limited inference for aggregates. Let's reuse the same facilities in the
AST when we calculate the safety of the foreign types.
2025-02-17 13:41:40 +00:00
Becca Royal-Gordon 12d0458eb2 Diagnose and forbid invalid Swift names on inits
Initializers should always have Swift names that have the special `DeclBaseName::createConstructor()` base name. Although there is an assertion to this effect in the constructor for ConstructorDecl, ClangImporter did not actually reject custom Swift names for initializers that violated this rule. This meant that asserts compilers would crash if they encountered code with an invalid `swift_name` attribute, while release compilers would silently accept them (while excluding these decls from certain checks since lookups that were supposed to find all initializers didn’t find them).

Modify ClangImporter to diagnose this condition and ignore the custom Swift name.
2025-02-11 12:05:17 -08:00
Gabor Horvath 1601564342 [cxx-interop] Import rvalue references as consuming parameters
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
2024-12-02 13:09:21 +00:00
Rintaro Ishizaki d4db99ce9d [Parse] Remove unnecessary dependencies to Parser.h
C++ swift::Parser is going to be replaced with SwiftParser+ASTGen.
Direct dependencies to it should be removed. Before that, remove
unnecessary '#include "swift/Parse/Parser.h"' to clarify what actually
depends on 'swift::Parser'.

Split 'swift::parseDeclName()' et al. into the dedicated files.
2024-11-02 01:23:59 -07:00
Ben Barham 2269b42d3d [ClangImporter] Correct check to ignore macro
The functionality of this function changed upstream in
https://github.com/llvm/llvm-project/pull/97274 and it now returns the
value of the character, rather than the character itself.
2024-08-05 19:53:15 -07:00
Ben Barham 226ba82525 [ClangImporter] Add various const
`getSelector` now takes a `const clang::IdentifierInfo *` `ArrayRef`.
Sprinkle a bunch of `const`s in.
2024-07-02 16:13:49 -07:00
Xi Ge 736ccef626 Merge remote-tracking branch 'apple/main' into rebranch 2024-06-20 15:16:55 -07:00
Tim Kientzle 598e5104ef Merge pull request #74184 from tbkka/tbkka-assertions2
Add `#include "swift/Basic/Assertions.h"` to a lot of source files
2024-06-20 12:13:28 -07:00
swift-ci 3aff53eb62 Merge remote-tracking branch 'origin/main' into rebranch 2024-06-19 03:34:03 -07:00
Gabor Horvath d17d17e96e [cxx-interop] Fix inadvertently renaming static method to Mutating
When we have both const and non-const version of a function, we import
the non-cont version with the "Mutating" suffix. This logic, however, is
redundant for static member functions as those can never be marked as
"const" since they don't have a "self" or "this" to mutate.

rdar://120858502
2024-06-18 16:19:23 +01:00
Tim Kientzle 1d961ba22d Add #include "swift/Basic/Assertions.h" to a lot of source files
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
2024-06-05 19:37:30 -07:00
Ben Barham a4405405a1 [ClangImporter] Rename SwiftVersionedAttr to SwiftVersionedAdditionAttr
Renamed in our LLVM fork 628ee3b842b1fcc93afdebc646220e8ae6302ed6.
2024-04-08 08:58:59 -07:00
Ben Barham 1fdda023b3 Rename StringRef::endswith references to StringRef::ends_with
Missed this when doing the `startswith` renaming. `endswith` has also
been deprecated upstream (and presumably soon to be removed).
2024-04-01 10:59:16 -07:00
Ben Barham 9779c18da3 Rename startswith to starts_with
LLVM is presumably moving towards `std::string_view` -
`StringRef::startswith` is deprecated on tip. `SmallString::startswith`
was just renamed there (maybe with some small deprecation inbetween, but
if so, we've missed it).

The `SmallString::startswith` references were moved to
`.str().starts_with()`, rather than adding the `starts_with` on
`stable/20230725` as we only had a few of them. Open to switching that
over if anyone feels strongly though.
2024-03-13 22:25:47 -07:00
Egor Zhdan 8ead7224b7 [cxx-interop] Overhaul virtual method support
This adds a new implementation of virtual method dispatch that handles reference types correctly.

Previously, for all C++ types an invocation of a virtual method would actually get dispatched statically. For value types this is expected and matches what C++ does because of slicing. For reference types, however, this is incorrect, we should do dynamic dispatch.

rdar://123852577
2024-03-01 19:45:58 +00:00
Ben Barham ef8825bfe6 Migrate llvm::Optional to std::optional
LLVM has removed llvm::Optional, move over to std::optional. Also
clang-format to fix up all the renamed #includes.
2024-02-21 11:20:06 -08:00
Doug Gregor 7e30d54deb [Clang importer] Map imported names via the user-facing name
Swift names provided via C attributes or API notes can be parsed as
special names, such as `init` or `subscript`. However, doing so would
cause the Clang importer to crash, because it assumes that these names
are always identifiers. In these places, we actually want to treat
them as identifiers, where special names are mapped back to their
keywords. Introduce a function to do that, and use it consistently.
2023-12-12 14:22:02 -08:00
Egor Zhdan efc008a2ca [cxx-interop] Import using decls that expose methods from private base classes
If a C++ type `Derived` inherits from `Base` privately, the public methods from `Base` should not be callable on an instance of `Derived`. However, C++ supports exposing such methods via a using declaration: `using MyPrivateBase::myPublicMethod;`.

MSVC started using this feature for `std::optional` which means Swift doesn't correctly import `var pointee: Pointee` for instantiations of `std::optional` on Windows. This prevents the automatic conformance to `CxxOptional` from being synthesized.

 rdar://114282353 / resolves https://github.com/apple/swift/issues/68068
2023-11-14 00:30:54 +00:00
Egor Zhdan a45d03a669 [cxx-interop] Use unique mangling for distinct C++ class template specializations
This makes sure we are printing more than one level of C++ template specializations when emitting a Swift struct name.

For instance, `std::__wrap_iter<char*>` and `std::__wrap_iter<const char*>` are currently imported with the same name in Swift. This means the mangled string will be the same for these specializations, despite them being distinct types. This causes mangling errors.

rdar://117485399
2023-10-26 13:29:41 +01:00
Evan Wilde 24d0db249b Merge remote-tracking branch 'main' into 'rebranch'
Conflicts:
  CMakeLists.txt
    Take new BRIDGING_MODE

  SwiftCompilerSources/Sources/SIL/GlobalVariable.swift
    Take new
2023-10-09 17:21:23 -07:00
Egor Zhdan 041005af7c [cxx-interop] Use more correct type names in C++ template parameters
When importing a C++ class template instantiation, Swift translates the template parameter type names from C++ into their Swift equivalent.

For instance, `basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t>>` gets imported as `basic_string<Scalar, char_traits<Scalar>, allocator<Scalar>>`: `wchar_t` is imported as `CWideChar`, which is a typealias for `Scalar` on most platforms including Darwin. Notice that Swift goes through the `CWideChar` typealias on the specific platform. Another instantiation `basic_string<uint32_t, char_traits<uint32_t>, allocator<uint32_t>>` also gets imported as `basic_string<Scalar, char_traits<Scalar>, allocator<Scalar>>`: `uint32_t` is also imported as `Scalar`. This is problematic because we have two distinct C++ types that have the same name in Swift.

This change makes sure Swift doesn't go through typealiases when emitting names of template parameters, so `wchar_t` would now get printed as `CWideChar`, `int` would get printed as `CInt`, etc.

This also encourages clients to use the correct type (`CInt`, `CWideChar`, etc) instead of relying on platform-specific typealiases.

rdar://115673622
2023-10-09 14:57:10 +01:00
swift-ci e50bfb85d5 Merge remote-tracking branch 'origin/main' into rebranch 2023-07-27 10:19:30 -07:00
Egor Zhdan b860fddd52 [cxx-interop] Fix assertion failure in IRGen with mutable dereference operators
I discovered this when experimenting with `std::map::iterator`, which has a const overload of `operator*` that returns a non-const reference, and does not have a const overload of `operator*`.

rdar://112471779
2023-07-27 15:54:09 +01:00
swift_jenkins 3326d91a2c Merge remote-tracking branch 'origin/main' into next 2023-07-25 08:22:24 -07:00
Egor Zhdan 8832d27e98 [cxx-interop] Import mutating dereference operators
C++ `T& operator*()` is mapped to a Swift computed property `var pointee: T`.

Previously `var pointee` only had a getter, after this change it will also have a setter if the C++ type declares an overload of `operator*` that returns a mutable reference.

rdar://112471779
2023-07-19 16:12:55 +01:00
Evan Wilde 26a974e772 [NFC] Headers headers headers!
Including headers that were being transitively included from LLVM
before. Also pointing them at the new locations for some of them.
2023-07-17 10:55:55 -07:00
Evan Wilde 8ce6ee8dd1 Updating API usages
LLVM deprecated, renamed, and removed a bunch of APIs. This patch
contains a lot of the changes needed to deal with that.

The SetVector type changed the template parameters.

APInt updated multiple names, countPopulation became popcount,
getAllOnesValue became getAllOnes, getNullValue became getZero, etc...

Clang type nullability check stopped taking a clang AST context.

The LLVM IRGen Function type stopped exposing basic block list directly,
but gained enough API surface that the translation isn't too bad.
(GenControl.cpp, LLVMMergeFunctions.cpp)

llvm::Optional had a transform function. That was being used in a couple
of places, so I've added a new implementation under STLExtras that
transforms valid optionals, otherwise it returns nullopt.
2023-07-17 10:53:42 -07:00
Evan Wilde 88cec51070 [NFC] Static cast optional bit-fields
llvm::Optional had a constructor that took a const l-value
reference, but std::optional does not, resulting in build failures when
returning bit-fields in optionals. Casting the bit-field to the
appropriate type fixes this.
2023-07-17 10:53:42 -07:00
Slava Pestov 40ea8c6721 ClangImporter: Remove unused variable 2023-07-12 12:42:42 -04:00
Egor Zhdan d4e8551281 [cxx-interop] Mangle numeric template arguments
This fixes linker errors when there are multiple instantiations of a templated struct with numeric template parameters.

When mangling the name of a C++ template specialization, we currently ignore non-type templated parameters. This causes two different instantiations of the same templated type to have the same mangled name, triggering linker errors.

rdar://107757051
2023-07-05 15:28:42 +01:00