Commit Graph

71 Commits

Author SHA1 Message Date
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
fahadnayyar
9782eae585 Merge pull request #77522 from fahadnayyar/cxx-frt-inheritance-diagnostics
[cxx-interop] Infer SWIFT_SHARED_REFERENCE for types inheriting from a C++ foreign reference type
2025-02-20 13:46:28 -08:00
fahadnayyar
d8f919778d [cxx-interop] [cxx-interop] Infer SWIFT_SHARED_REFERENCE for types inheriting from a C++ foreign reference type
rdar://97914474
2025-02-20 08:46:57 -08: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
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
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
250082df25 [NFC] Reformat all the LLVMs
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.
2023-06-27 09:03:52 -07:00
Evan Wilde
f3ff561c6f [NFC] add llvm namespace to Optional and None
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.
2023-06-27 09:03:52 -07:00
Alex Lorenz
d4aa18ab9f [cxx-interop][index] emit symbolic interface files for C++ modules 2023-01-31 14:58:19 -08:00
Alex Lorenz
f36e5cf641 [interop] add 'ImportSymbolicCXXDecls' experimental import mode for importing class templates syntactically but not semantically 2023-01-31 14:58:13 -08:00
Josh Soref
3d488f685e Spelling clangimporter (#42464)
* spelling: enumerators

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: handler

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: heuristic

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: implicitly

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: included

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: instantiate

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: integer

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: nested

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: otherthing

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: overridden

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: simultaneously

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: special

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: typecheck

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unfortunately

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unknown

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: version

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-21 09:31:12 -07:00
Becca Royal-Gordon
8c844126d4 [ClangImporter] Make completion handlers Sendable
If a method has an `async` variant, the non-`async` variant will now mark its completion handler parameter `@Sendable`. This shouldn't be a breaking change in Swift 5 code since these declarations are automatically `@_predatesConcurrency`.

Also adds:

• Support for `@_nonSendable` on parameters, which can be used to override this implicit `@Sendable`
• Support for `@Sendable` on block typedefs; it's generally going to be a good idea to mark completion block typedefs `@Sendable`.

Fixes rdar://85569247.
2022-01-25 15:49:54 -08:00
Saleem Abdulrasool
714eaefc78 Importer: remove ImportAsMember support
This functionality is not actively in use and the last usage of this has
been removed.  Remove the infrastructure that is no longer in need.
2021-03-22 08:53:56 -07:00
Doug Gregor
77105a4ee5 Enable SE-0297: Concurrency Interoperability with Objective-C 2021-02-24 14:18:16 -08:00
Joe Groff
3edaa70c28 Augment ForeignAsyncConvention with fields for completion handler flag params.
When the requisite support in Clang for `__attribute__((swift_async_error))` parameters
lands, this will let us represent APIs that take completion handlers in the general shape
of `void (^)(BOOL, id, NSError*)`, where the boolean argument indicates the presence of
an error rather than the nilness of the `NSError*` argument.
2021-02-11 13:38:30 -08:00
Doug Gregor
3cd115e283 [Concurrency] Implement support for swift_async attribute.
The `swift_async` attribute helps control how a method is imported as
`async` into Swift.

Implements rdar://70111787.
2020-12-06 23:21:18 -08:00
Doug Gregor
abe0308c21 [Concurrency] Adopt Clang swift_async_name attribute.
The new `swift_async_name` attribute allows Clang declarations to specify
their Swift names only for `async` import, which may differ from those used
for importing as a completion handler.

Implements rdar://70111787.
2020-12-06 22:42:24 -08:00
Doug Gregor
16104d8045 [Concurrency] Don't lose name information from completion-handler arguments.
When a completion handler parameter has a selector piece that ends with
"WithCompletion(Handler)", prepend the text before that suffix to the
base name or previous argument label, as appropriate. This ensures that
we don't lose information from the name, particularly with delegate names.
2020-10-22 13:32:03 -07:00
Doug Gregor
24ea8becc8 [Concurrency] Move removal of leading "get" for async imports.
Name adjustments should be performed by omitNeedlessWords(), not the
early classifcation of async imports.
2020-10-21 21:48:52 -07:00
Doug Gregor
e1852956a0 [Concurrency] Drop "get" prefix when importing Objective-C methods as async.
Implements rdar://70506634.
2020-10-21 12:33:49 -07:00
Doug Gregor
0f18948bd5 [Concurrency] Allow @objc async methods.
Allow the declaration of @objc async methods, mapping them to a
completion-handler API in Objective-C. This covers most of the
checking and semantics within the type checker:
* Declaring @objc async methods and checking their parameter/result types
* Determining the default Objective-C selector by adding
completionHandler/WithCompletionHandler as appropriate
* Determining the type of the completion handler parameter
* Inferring @objc from protocol requirements
* Inferring @objc from an overridden method
2020-09-08 10:15:24 -07:00
Doug Gregor
1e5d30f5ca [Concurrency] Import Objective-C methods with completion handlers as async
When a given Objective-C method has a completion handler parameter
with an appropriate signature, import that Objective-C method as
async. For example, consider the following CloudKit API:

    - (void)fetchShareParticipantWithUserRecordID:(CKRecordID
*)userRecordID
            completionHandler:(void (^)(CKShareParticipant * _Nullable shareParticipant, NSError * _Nullable error))completionHandler;

With the experimental concurrency model, this would import as:

    func fetchShareParticipant(withUserRecordID userRecordID: CKRecord.ID) async throws -> CKShare.Participant?

The compiler will be responsible for turning the caller's continuation
into a block to pass along to the completion handler. When the error
parameter of the completion handler is non-null, the async call
will result in that error being thrown. Otherwise, the other arguments
passed to that completion handler will be returned as the result of
the async call.

async versions of methods are imported alongside their
completion-handler versions, to maintain source compatibility with
existing code that provides a completion handler.

Note that this only covers the Clang importer portion of this task.
2020-08-27 21:30:13 -07:00
Ted Kremenek
8c1148784a Merge pull request #15516 from tkremenek/version-4_2-importname
Translate effective version name of '4.x' to '4.2' for ImportNameVersion.
2018-11-06 15:51:39 -08:00
Bob Wilson
c3e02955bb [master-next] Adjust for VersionTuple moving from clang to llvm.
LLVM r334399 (and related Clang changes) moved clang::VersionTuple to
llvm::VersionTuple. Update Swift to match.

Patch by Jason Molenda.
rdar://problem/41025046
2018-06-12 16:44:11 -07:00
Rintaro Ishizaki
b3453c17fe [ClangImporter] Take isCompatibilityAlias() into account in interface printing (#16625)
If the Clang declrations are *types*, canonical declaration in Swift is
imported for newest version of Swift. In interface generation, if the
declaration is versioned and it's imported as a member in either or both
version of Swift, we have to take compatibility typealias into account.

* Fixed 'ClangModuleUnit::getTopLevelDecls' to take isCompatibilityAlias() into account
* Fixed bugs in ClangImporter where member-to-member versioned types aren't properly imported.
  * Fixed 'SwiftDeclConverter::importFullName' to check equality of getEffectiveContext()
  * Fixed 'importer::addEntryToLookupTable' to check equality of getEffectiveContext()
    (moved 'ClangImporter::Implementation::forEachDistinctName' to 'NameImporter')
2018-05-22 13:38:45 +09:00
Ted Kremenek
a2951aa052 Translate effective version name of '4.x' to '4.2' for ImportNameVersion for x >= 2. 2018-03-26 10:51:51 -07:00
Ted Kremenek
3da51018b6 Teach ClangImporter to handle effective Swift version with minor release.
Needed to support Swift 4.2.
2018-03-23 00:30:44 -07:00
Jordan Rose
00b890f9f1 [ClangImporter] Stop copying EnumInfo strings into Swift's ASTContext
They're all kept alive by Clang's ASTContext already. Since the enum
info is only accessible through the Clang importer, that's a
sufficient lifetime. (Note that this only works because all of the
strings are derived from text actually present in the C sources:
either attribute arguments or names of declarations.)

Fixes a small TODO and probably saves a tiny bit of memory usage.
2018-01-04 15:06:26 -08:00
Doug Gregor
a49455e3b2 [Clang importer] Move the "all properties" lists into the name importer.
Swift's ASTContext contained all of the logic to find the complete list
of properties for an Objective-C class, which is used by the Clang importer
to influence the mapping of Objective-C names into Swift. Swift's
ASTContext also included a *cache* for this information, indexed by
the Clang `ObjCInterfaceDecl *`. However, this cache was getting
populated/queried from the Clang importer's name importer, such that
the keys would be Clang declarations used to build modules and then
deallocated. If that memory eventually gets reused for a different
`ObjCInterfaceDecl *`, we would get incorrect/stale all-properties
information.

Almost Surely fixes rdar://problem/35347167, which is a
nondeterministic failure where UIView's `addGestureRecognizer(_:)` gets
occasionally imported as `add(_:)`.
2017-11-08 15:25:15 -08:00
Jordan Rose
a0117b0cd0 [ClangImporter] Bump the maximum supported version to Swift 5
"...finally."

This was technically enabled two commits ago, since nothing checks
that you're not /over/ maxVersion(). This is only used for

- deciding the canonical way to import renamed types
- trying to import things in multiple ways

...and so there are very few observable differences, especially
before anyone has added any API notes that differentiate Swift 4
and Swift 5.

At some point we should start encoding name versions in the lookup
tables so that we only have to try all the names /once/, but the test
suite doesn't seem to get measureably slower with this change,
probably because it's pretty quick to decide that most things don't
have multiple names. So we can put that off until later.
2017-09-15 14:30:24 -07:00
Jordan Rose
9a04bee421 [ClangImporter] Turn ImportNameVersion into a struct.
...so that we don't have to keep coming back to update it every major
release. And also so we can actually put methods on it instead of
using free functions.

No intended behavior change (yet).
2017-09-15 14:30:24 -07:00
Jordan Rose
ff31714b69 [ClangImporter] ImportedName doesn't need to know its version.
Preparation for making ImportNameVersion a generalized struct rather
than an enum. We could have kept cramming it into a bitfield, sure,
but we don't actually need this.

No intended functionality change.
2017-09-11 18:06:35 -07:00
Jordan Rose
9a9d139320 [ClangImporter] Import Swift 3 and 4 names for enumerators. (#9523)
Also lays the groundwork for rdar://problem/16513537, which is about
being able to find an enum by its original top-level name so that we
can show a diagnostic for that. I'll file a public bug about that
later.

rdar://problem/31893305
2017-05-12 14:51:40 -07:00
Jordan Rose
cb9b9ea734 [ClangImporter] Always import types under their Swift 4 name.
This means all cross-module references and all mangled names will
consistently use the Swift 4 name (the canonical type), no special
handling required.

The main thing we lose here is that the Swift 4 names of imported
types become usable in Swift 3 mode without any diagnostics, similar
to how most language features introduced in Swift 4 are available in
Swift 3 mode. It also implies that the Swift 4 name will show up in
demangled names.

rdar://problem/31616162
2017-04-26 13:07:03 -07:00
Jordan Rose
f7562e42b6 [ClangImporter] Add versioned stubs for import-as-member renames. (#8272)
A more general solution to ae458a84ad: import all versions of a name
that are going to show up as members, ignore those that aren't.

Further work on <rdar://problem/29170671> Import APIs under their
Swift 3 names.
2017-03-23 13:46:51 -07:00
Jordan Rose
c9124d989d [ClangImporter] Import Swift 3 versions of top-level decls in Swift 4.
...and Swift 4 versions in Swift 3, and Swift 2 and "raw" versions in
both. This allows the compiler to produce sensible errors and fix-its
when someone uses the "wrong" name for an API. The diagnostics
certainly have room to improve, but at least the essentials are there.

Note that this commit only addresses /top-level/ decls, i.e. those
found by lookup into a module. We're still limited to producing all
members of a nominal type up front, so that'll require a slightly
different approach.

Part of rdar://problem/29170671
2017-02-24 14:01:10 -08:00
Jordan Rose
ce810efe75 [ClangImporter] Route getFactoryAsInit through findSwiftNameAttr.
The next commit will make findSwiftNameAttr handle Swift 3 / Swift 4
API notes, so it's important that everything is consistently using it.
(The other place that isn't updated yet is enum info; conceivably, the
prefix for enum constants might be different based on which
SwiftNameAttrs are in play.
2017-02-24 13:26:22 -08:00
Jordan Rose
a5da848064 [ClangImporter] Put all versions of names into the lookup table.
The compiler uses the non-active names to import unavailable
declarations telling the user the correct name. Right now it's still
only importing "Swift 2" and "current", but that should change.

For reference, the best example of a declaration that has four names
is a factory method with a custom NS_SWIFT_NAME annotation:

- Its raw name is the plain Objective-C name, written as a method:
  'fooByFrobnicatingBar(_:)'.
- Its "Swift 2" name is the Swift-2-style translation of that to an
  initializer: 'init(byFrobnicatingBar:)'
- Its "Swift 3" name applies the "omit needless words" transformation:
  'init(frobnicating:)'.
- Its "Swift 4" name uses the name specified by NS_SWIFT_NAME.
2017-02-24 13:26:21 -08:00
Xi Ge
b32424953e [SourceKit] Add a new request to translate from Objc names to Swift names and vice versa.
Extensive cross-language tooling support needs to bridge decl names between two different languages more freely. This SourceKit request is designed to translate Objc names to Swift names and vice versa. Working similarly to cursor-info requisition, the name translation request requires a Swift reference to a Swift/Clang decl, and the preferred name to translate from, and language kind that the given name belongs to. If the translation succeeds, SourceKit service responds with the corresponding name than belongs to the other kind of language.

Newly introduced keys:

“key.namekind": “source.lang.name.kind.objc” | "source.lang.name.kind.swift"
“key.basename”: “name"
“key.argnames”: [“name"]
“key.selectorpieces”: [“name[:]"]

This commit only implements translation from Objc to Swift.
2017-02-10 17:50:12 -08:00
practicalswift
6d1ae2a39c [gardening] 2016 → 2017 2017-01-06 16:41:22 +01:00
Jordan Rose
d1e087797c [ClangImporter] "Fix" too-wide bitfield.
Maximum value of an enum != number of bits required.
2016-12-22 17:32:32 -08:00
Michael Ilseman
1e42a16247 [Clang Importer] Plumb versions everywhere
Remove all occurrences of a "useSwift2Name" bool, and replace it with
version plumbing. This means that ImportDecl is now entirely
version-based, and the importer Impl knows versions. This will be
needed for marking Swift 3 names as deprecated, when there is a new
Swift 4 name.

NFC.
2016-12-14 19:55:14 -08:00
Michael Ilseman
e9613dccc7 [Import Name] Finish weaning importName() off of options.
Switch all of ImportName over to be version based, including
internally. NFC.
2016-12-14 13:28:48 -08:00
Michael Ilseman
623038bc1c Incorporate review feedback 2016-12-12 15:29:24 -08:00
Michael Ilseman
9bc065f73d [Clang Importer] Shrink ImportedName more
Re-arrange and repack some bits to bring the size of ImportedName down
to 5 pointers. The size will start to become important as we're going
to be storing one for every Swift version we want diagnostics for per
every Clang decl we might import.
2016-12-12 13:49:27 -08:00
Michael Ilseman
a21d1827a9 [Clang Importer] Unified ForeignErrorConvention
Expose a ForeignErrorConvention::Info struct, so that the
ClangImporter can also utilize this space-efficient
storage. Eliminates the ClangImporter's ad-hoc representation, and
shaves off a pointer or so off of the ImportedName size.

While we're out it, make some of the bools bitfields to shave off
another pointer in size. Total ImportedName size is now 6.
2016-12-12 13:29:26 -08:00
Michael Ilseman
01ee1eee61 [Clang Importer] Shave space off EffectiveClangContext/ImportedName
Shave off a pointer from the EffectiveClangContext, by re-arranging
some of its data. Down to 2 pointers from 3.

Inside of ImportName, factor out the does-it-have-a-value from
multiple stored Optionals so as to shave off a couple of
pointers. Present the same programming interface as before. Down to 8
pointers in size from 10, and still much further to go.
2016-12-12 13:22:36 -08:00
Michael Ilseman
2b01c25364 [Import Name] Refactor ImportedName to be a class
Change the interfaces to ImportedName to be method based, rather than
direct struct field accesses. We're going to be changing how these are
used in the future. Also, we will be storing large quantities of
these, so we will soon want to crunch down on their size.
2016-12-05 08:57:18 -08:00
Michael Ilseman
68737b78c2 [ClangImporter] Refactor name importing to be version based
Rather than use importName using a set of options of what to choose,
phrase the API in terms of language version. Be explicit about what
version is being requested at the call site, as it's a necessary
consideration for the client.
2016-12-03 13:26:08 -08:00