Use `resetBenignCodeGenOptions()` from clang dependency scanner to clear
the swift explicit module build cc1 arguments. This fixes the problem
that CurrentWorkingDirectory is leaking through
`-fcoverage-compilation-dir` that can cause extra module variants when
caching is enabled. This also avoid the duplicating the logics for
clearing CodeGen options inside Swift.
rdar://151395300
After removing the CASFS implementation for clang modules, there is no
need to capture clang extra file that sets up the VFS for the clang
modules since all content imported by ClangImporter is dependency
scanned and available via include-tree. This saves more ClangImporter
instance when caching is enabled.
Update the test to check that clang content found via `-Xcc` VFS options
can currently work without capture the headermaps and vfs overlays.
Using IncludeTree::FileList to concat the include tree file systems that
are passed on the command-line. This significantly reduce the
command-line size, and also makes the cache key computation a lot
faster.
rdar://148752988
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.
In Swift 6.1, we introduced `SWIFT_RETURNS_RETAINED` and
`SWIFT_RETURNS_UNRETAINED` annotations for C++ APIs to explicitly
specify the ownership convention of `SWIFT_SHARED_REFERENCE` type return
values.
Currently the Swift compiler emits warnings for unannotated C++ APIs
returning `SWIFT_SHARED_REFERENCE` types. We've received some feedback
that people are finding these warnings useful to get a reminder to
annotate their APIs. While this improves correctness , it also imposes a
high annotation burden on adopters — especially in large C++ codebases.
This patch addresses that burden by introducing two new type-level
annotations:
- `SWIFT_RETURNED_AS_RETAINED_BY_DEFAULT`
- `SWIFT_RETURNED_AS_UNRETAINED_BY_DEFAULT`
These annotations allow developers to specify a default ownership
convention for all C++ APIs returning a given
`SWIFT_SHARED_REFERENCE`-annotated type, unless explicitly overridden at
the API by using `SWIFT_RETURNS_RETAINED` or `SWIFT_RETURNS_UNRETAINED`.
If a C++ class inherits from a base class annotated with
`SWIFT_RETURNED_AS_RETAINED_BY_DEFAULT` or
`SWIFT_RETURNED_AS_UNRETAINED_BY_DEFAULT`, the derived class
automatically inherits the default ownership convention unless it is
explicitly overridden. This strikes a balance between safety/correctness
and usability:
- It avoids the need to annotate every API individually.
- It retains the ability to opt out of the default at the API level when
needed.
- To verify correctness, the user can just remove the
`SWIFT_RETURNED_AS_(UN)RETAINED_BY_DEFAULT` annotation from that type
and they will start seeing the warnings on all the unannotated C++ APIs
returning that `SWIFT_SHARED_REFERENCE` type. They can add
`SWIFT_RETURNS_(UN)RETAINED` annotation at each API in which they want a
different behaviour than the default. Then they can reintroduce the
`SWIFT_RETURNED_AS_(UN)RETAINED_BY_DEFAULT` at the type level to
suppress the warnings on remaining unannotated APIs.
A global default ownership convention (like always return
`unretained`/`unowned`) was considered but it would weaken the
diagnostic signal and remove valuable guardrails that help detect
use-after-free bugs and memory leaks in absence of
`SWIFT_RETURNS_(UN)RETAINED` annotations. In the absence of these
annotations when Swift emits the unannotated API warning, the current
fallback behavior (e.g. relying on heuristics based on API name such as
`"create"`, `"copy"`, `"get"`) is derived from Objective-C interop but
is ill-suited for C++, which has no consistent naming patterns for
ownership semantics.
Several codebases are expected to have project-specific conventions,
such as defaulting to unretained except for factory methods and
constructors. A type-level default seems like the most precise and
scalable mechanism to support such patterns. It integrates cleanly with
existing `SWIFT_SHARED_REFERENCE` usage and provides a per-type opt-in
mechanism without global silencing of ownership diagnostics.
This addition improves ergonomics while preserving the safety benefits
of explicit annotations and diagnostics.
rdar://145453509
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
Similarly to how https://github.com/swiftlang/swift/pull/70564 configures 'ClangImporter's 'CodeGenerator' using Swift's compilation target triple, we must use the versioned version of the 'isWeakImported' query to determine linkage for imported Clang symbols.
It is possible for a C++ class template to inherit from a specialization
of itself. Normally, these are imported to Swift as separate (unrelated)
types, but when symbolic import is enabled, unspecialized templates are
imported in place of their specializations, leading to circularly
inheriting classes to seemingly inherit from themselves.
This patch adds a check to guard against the most common case of
circular inheritance, when a class template directly inherits from
itself. This pattern appears in a recent version of libc++,
necessitating this patch. However, the solution here is imperfect as it
does not handle more complex/contrived circular inheritance patterns.
This patch also adds a test case exercising this pattern. The
-index-store-path flag causes swift-frontend to index the C++ module
with symbolic import enabled, without the fix in this patch, that test
triggers an assertion failure due to the circular reference (and can
infinitely recurse in the StorageVisitor when assertions are disabled).
rdar://148026461
Currently, ClangImporter has some logic to pick the default arm64
target CPU (when -target-cpu isn't passed) based on the target OS
and arch variant.
This was originally done long ago in 3cf3f42e98, and later
maintained through 49a6c8eb7b, because it was necessary when
clang (targeting darwin) relied on -arch to set this sort of default.
Clang has migrated to full -target triples for a while now, and has
sophisticated logic for picking default target CPUs and features based
on the target triple.
Currently, we override that by passing our -mcpu explicitly.
Instead, allow clang to pick its defaults, and only pass -mcpu
when asked via -target-cpu.
This is visible in the test, with arm64 macOS now defaulting to M1.
The same applies to simulators, per Triple::isTargetMachineMac.
rdar://148377686
When serializing `@available` attributes, if the attribute applies to a custom
domain include enough information to deserialize the reference to that domain.
Resolves rdar://138441265.
Partially revert https://github.com/swiftlang/swift/pull/80035 now that Clang
has its own APIs for querying serialized modules for the decl representing the
availability domain with a given name.
To trigger this error one needs to import a nested type from C++, use it
in a generic context in Swift, and export it back to C++. We were
inconsisent in what namespace did we declare the functions to get the
type metadata for types. It was in the swift namespace for foreign types
and in the module namespace for Swift types. This PR standardizes on how
the metadata function is declared and called to fix the issue.
Fixes#80538.
rdar://148597079
When loading a module with embedded bridging header, bind the bridging
header module in the context when bridging header auto chaining is used.
This is because all the bridging header contents are chained into a PCH
file so binary module with bridging header should reference the PCH file
for all declarations.
rdar://148538787
This patch fixes the access check for nested private C++ enums to look for the SWIFT_PRIVATE_FILEID of the enclosing C++ class, if any. Previously, the check was looking at for SWIFT_PRIVATE_FILEID on the enum decl itself (which is meaningless); that prevented nested private enum members from being accessible in Swift.
This patch also specializes the type signature of getPrivateFileIDAttrs to clarify the fact that SWIFT_PRIVATE_FILEID is not a meaningful annotation on anything other than CXXRecordDecl, because that is the only kind of decl that can assign access specifiers to its members.
rdar://148081340
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
ABI-only declarations now query their API counterpart for things like `isObjC()`, their ObjC name, dynamic status, etc. This means that `@objc` and friends can simply be omitted from an `@abi` attribute.
No tests in this commit since attribute checking hasn’t landed yet.
Currently, we only get warnings for using unsafe types in expressions
but not in the function signature. The tests did not use the std::string
object in the function body. As a result, we regressed and std::string
was considered unsafe.
The reason is that the annotation only mode for calculating escapability
of a type did not do what we intended. std::basic_string is
conditionally escapable if the template argument is escapable. We
considered 'char' to have unknown escapability in annotation only mode.
The annotation only mode was introduced to avoid suddenly importing
certain types as not escapable when they have pointer fields and break
backward compatibility.
The solution is to make annotation only mode to still consider char and
co as escapable types and only fall back to unknown when the inference
otherwise would have deduced non-escapable (for unannotated typed).
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 is very brittle in this first iteration. For now we require the
declaration representing the availability domain be deserialized before it can
be looked up by name since Clang does not have a lookup table for availabilty
domains in its module representation. As a result, it only works for bridging
headers that are not precompiled.
Part of rdar://138441266.
Lookup into C++ namespaces uses a different path from C++ record declarations.
Augment the C++ namespace lookup path to also account for the auxiliary
declarations introduced by peer macro expansions.
When performing name lookup into a C++ record type, make sure that we
also walk through auxiliary declarations (i.e., declarations that can
come from peer macro expansions) to find results.
Fixes rdar://146833294.
It is possible for a module interface (e.g., ModuleA) to be generated
with C++ interop disabled, and then rebuilt with C++ interop enabled
(e.g., because ModuleB, which imports ModuleA, has C++ interop enabled).
This circumstance can lead to various issues when name lookup behaves
differently depending on whether C++ interop is enabled, e.g., when
a module name is shadowed by a namespace of the same name---this only
happens in C++ because namespaces do not exist in C. Unfortunately,
naming namespaces the same as a module is a common C++ convention,
leading to many textual interfaces whose fully-qualified identifiers
(e.g., c_module.c_member) cannot be correctly resolved when C++ interop
is enabled (because c_module is shadowed by a namespace of the same
name).
This patch does two things. First, it introduces a new frontend flag,
-formal-cxx-interoperability-mode, which records the C++ interop mode
a module interface was originally compiled with. Doing so allows
subsequent consumers of that interface to interpret it according to the
formal C++ interop mode. Note that the actual "versioning" used by this
flag is very crude: "off" means disabled, and "swift-6" means enabled.
This is done to be compatible with C++ interop compat versioning scheme,
which seems to produce some invalid (but unused) version numbers. The
versioning scheme for both the formal and actual C++ interop modes
should be clarified and fixed in a subsequent patch.
The second thing this patch does is fix the module/namespace collision
issue in module interface files. It uses the formal C++ interop mode to
determine whether it should resolve C++-only decls during name lookup.
For now, the fix is very minimal and conservative: it only filters out
C++ namespaces during unqualified name lookup in an interface that was
originally generated without C++ interop. Doing so should fix the issue
while minimizing the chance for collateral breakge. More cases other
than C++ namespaces should be added in subsequent patches, with
sufficient testing and careful consideration.
rdar://144566922
https://github.com/swiftlang/swift/pull/37774 added '-clang-target' which allows us to specify a target triple that only differs from '-target' by the OS version, when we want to provide a different OS version for API availability and type-checking, in order to set a common/unified target triple for the entire Clang module dependency graph, for presenting a unified API surface to the Swift client, serving as a maximum type-checking epoch.
This change adds an equivalent flag for the '-target-variant' configuration, as a mechanism to ensure that the entire module dependency graph presents a consistent os version.
ClangImporter can now import non-public members as of be73254cdc and 66c2e2c52b, but doing so triggers some latent ClangImporter bugs in projects that don't use or need those non-public members.
This patch introduces a new experimental feature flag, ImportNonPublicCxxMembers, that guards against the importation of non-public members while we iron out those latent issues. Adopters of the SWIFT_PRIVATE_FILEID feature introduced in bdf22948ce can enable this flag to opt into importing private members they wish to access from Swift.
rdar://145569473
https://github.com/swiftlang/swift/pull/79270 taught the dependency scanner to ignore `-file-compilation-dir` when caching is
_not_ in effect but did not make the corresponding change when caching is in effect. This PR teaches the scanner to ignore `-file-compliation-dir` when caching is in effect.
rdar://146025100
It turns out the query to check the reference semantics of a type had
the side effect of importing some functions/types. This could introduce
circular reference errors with our queries. This PR removes this side
effect from the query and updates the test files. Since we do the same
work later on in another query, the main change is just the wording of
the diagnostics (and we now can also infer immortal references based on
the base types). This PR also reorders some operations, specifically now
we mark base classes as imported before we attempt to import template
arguments.
After these changes it is possible to remove the last feature check for
strict memory safe mode. We want to mark types as @unsafe in both
language modes so we can diagnose redundant unsafe markers even when the
feature is off.
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
This allows combining __counted_by and std::span for safe interop.
Previously we disabled this in C++ mode due to issues when bounds
attributes occurred directly or indirectly in templated contexts, but
this has now been resolved on the clang side.
This patch introduces an a C++ class annotation, SWIFT_PRIVATE_FILEID,
which will specify where Swift extensions of that class will be allowed
to access its non-public members, e.g.:
class SWIFT_PRIVATE_FILEID("MyModule/MyFile.swift") Foo { ... };
The goal of this feature is to help C++ developers incrementally migrate
the implementation of their C++ classes to Swift, without breaking
encapsulation and indiscriminately exposing those classes' private and
protected fields.
As an implementation detail of this feature, this patch introduces an
abstraction for file ID strings, FileIDStr, which represent a parsed pair
of module name/file name.
rdar://137764620