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
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
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
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
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
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.
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.
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
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.
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
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)
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.
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
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.
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
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
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
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
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
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.
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.
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
Reformatting everything now that we have `llvm` namespaces. I've
separated this from the main commit to help manage merge-conflicts and
for making it a bit easier to read the mega-patch.
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".
I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
The `isBoolType` operation within the Clang importer has a historical
definition that excludes the C++ `bool` and its use in C as an
extension. Retain that definition, and check for the actual `bool`
when importing C++ conversion functions into Swift.
Fixes two regressions in the Clang importer:
1. We started to import `bool`-typed Objective-C properties with their
getter names.
2. We started importing `bool`-typed Objective-C methods with an
NSError** parameter as `throws`.
Both of these changes could be considered improvements, but they
cannot be made without breaking source compatibility, so roll those
changes back to maintain source compatibility.
We should have a separate discussion about enabling this behavior for
Swift >= 6.
Instead of mangling class template specializations with the prefix "__CxxTemplateInst," simply set the decl name as the class templates plus the types that it is specialized on (so `vector<Int>` rather than `__CxxTemplateInstNSt3__16vectorIi...`).
This is mainly to improve diagnostics. As a side effect of this change, if anyone copies the name of a class template specializaiton from an error/warning and uses it in source code, the compiler will error (that class templates aren't available in swift) rather than silently passing only to cause serailization failures down the road.