The implementation for this behavior was added in a previous patch;
this patch integrates and removes unused call sites.
This patch also adds some tests exercising the overloading behavior.
Annoyingly, imported members that point to the same source location
aren't sorted correctly in the module interface, so this changes the
order in a bunch of module interface tests.
rdar://170857428
Also, un-comment broken test case of using Base::operator[], which is
fixed by this commit.
rdar://145345345
This reduces the code size and also standardizes code. In some cases we
fixed a bug at one version of the "inlined helper" but not at the other.
Hopefully, the deduplicated code makes it less likely that we run into
similar situations.
It is possible to get into situations where we have a derived FRT whose
definition is not reachable (in the modules sense). This is problematic
when we need to synthesize reference counting operations for derived
those FRTs via clang::Sema, because those operations require knowledge
about the layout of those classes, i.e.,
Base::ref((Base *)derived) // otherwise-implicit cast added for emphasis
As such, clang::Sema would be unable to generate valid call expressions,
leading to assertion failures in the decl synthesizer logic which
assumed everything is hunky dory.
This patch adds logic to accommodate this scenario, throwing a compiler
error when reachability is an problem, so that the user can look into
possible modulemap/module layout issues.
rdar://172291423
We'll still see error messages from Clang if the results are invalid for
any reason, but at least the compiler won't assertions-fail or generate
garbo ASTs.
rdar://172291423
cast<clang::FunctionDecl>(releaseResult.operation->getClangDecl()) would
crash when getClangDecl() returns a nulptr, which happens when the
operation is a synthesized inherited function.
rdar://172291423
Previously Swift imported default argument expressions in C++ methods and global functions, but not constructors.
rdar://118987713 / resolves https://github.com/apple/swift/issues/70124
This was previously used to control whether a CxxRecordSemantics or
CxxRecordAsSwiftType request would trigger diagnostics when determining
a type is a foreign reference type. That interface led to obscure
control flow and was removed recently. This patch removes the vestigial
pointer field those requests used.
(Actually, that pointer was *never* used by CxxRecordAsSwiftType
requests; its call sites just happened to pick it up because it shares
the same input descriptor type as CxxRecordSemantics).
rdar://170858418
Previously, the getRefParentOrDiag() function was used both to determine
the reference typedness of an imported record, and to diagnose cases
where that determination was invalid (e.g., due to complications that
arise from inheritance). However, it exposed a rather brutish interface
for controlling whether diagnostics are emitted: when it is given
a non-null ClangImporter::Implementation pointer, it emits diagnostics,
and when given a null pointer it doesn't. A lack of consideration for
where we actually needed these diagnostics led to that pointer being
unnecessarily threaded through a couple of requests and a half dozen
call sites, leading to unnecessarily obscure control flow.
This patch gets rid of getRefParentOrDiag() and replaces it with two
well-defined entry points: a request that does not emit diagnostics, and
a function that does. The nullable ClangImporter::Implementation pointer
is hidden from the interface of those entry points, and their side
effects are well-documented.
The code is migrated from ClangImporter.cpp to ClangAnalysis.cpp, which
I've introduced as the new home for various subroutines that analyze and
extract information from clang decls.
The reference type inference logic of getRefParentOrDiag() (and its
associated helpers) is also rewritten to replace the clang-provided
clang::CXXRecordDecl::forAllBases() with an explicit graph traversal
through the class hierarchy that is easier to debug and adjust (with
imminent behavior changes in mind). It also avoids an unnecessary
class hierarchy traversal whose only purpose was to look for reference
types that participates in diamond inheritance.
No behavior change is intended: we (should) still make perform the same
reference typedness analysis, and emit the exact same diagnostics.
rdar://170858418
* 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
Modify relevant portions of the type-checker and parser to allow, when the 'LiteralExpressions' experimental feature is enabled, for arbitrary integer-typed expressions in enum raw value specifiers. These expressions will be type-checked and constant-folded into an integer literal expression, keeping the current interface of 'EnumElementDecl' consistent for clients.
Previously, 'EnumRawValuesRequest' had two different "modes" which were discerned based on typechecking stage (structural | interface), where the former had the request compute all raw values, both user-specified literal expressions and computing increment-derived values as well; the latter would also type-check the user-specified expressions and compute their types.
- With the need to have enum case raw values support arbitrary integer expressions, the request ('EnumRawValuesRequest') has been refactored and simplified to *always* both compute all case raw values and perform type-checking of user-specified raw value expressions. This is done in order to allow the AST-based constant-folding infrastructure ('ConstantFoldExpression' request) to run on the expressions. Constant folding is invoked during the evaluation of 'EnumRawValuesRequest' on all user-specified raw value expressions, in order to be able to compute subsequent increment values and ensure the expressions are foldable. If they are not, i.e. if constant folding fails, a relevant diagnostic will be emitted.
- 'EnumElementDecl' continues to store the raw value expression, which is no longer a 'LiteralExpr' but rather an 'Expr'; however, the getter ('getRawValueExpr') continues to return a 'LiteralExpr' by invoking the constant-folding request on the stored value, which is guaranteed to return a cached result from a prior invocation in 'EnumRawValuesRequest', assuming it succeeded.
- Furthermore, the 'structural' request kind was previously not cached, whereas now because the request must always do the complete type-checking work, it is always cached.
Resolves rdar://168005520
We were previously marking synthesized FRT initializers as
"returns_retained" unconditionally (for non-immortal types), which can
cause memory errors and also suppresses diagnostics about the lack of
such annotations.
This patch fixes that behavior, and also adjusts the source locations of
the synthesized C++ factory method to point to the actual constructor
decl when its location is available, so that the diagnostics make sense
when warning about the lack of annotations.
rdar://163127315
This scenario happens when a derived class inherits operator[] from
a base class. The derived class's operator[] is a synthesized shim,
which (currently) does not have a ClangNode associated with it.
This prevents an assertion failure in SubscriptDecl::createImported().
rdar://167701851
C++ allows function templates that do not use all of their template parameters in the signature, such as:
```
template <typename T>
bool foo();
```
This is not compatible with Swift's generic model, so to let clients call such functions from Swift, ClangImporter generates an extra metatype parameter:
```
func foo<T>(T: T.Type) -> Bool
// Usage:
foo(Int.self)
foo(Bool.self)
```
That logic had a flaw that surfaced when the C++ function's behavior differs depending on the templated parameter. Instead of instantiating the function template with all of the required template parameters, and using the corresponding instantiation for each call, Swift was (correctly) instantiating the template for the necessary types, but then silently dropping all of the instantiations except for one, and using the remaining one for all callsites. This happened because all of the instantiations were getting the same name in Swift, and therefore had the exact same mangled name, which caused SILGen to pick one and discard the others.
This makes sure that if the extra metatype parameter was added to a function template, all of the function instantiations get unique mangled names.
rdar://166184513
Follow up for #86124. I forgot to update on of the branches to use Sema
to build the call expression, so the implicit casts responsible for the
offset adjustments did not get inserted. Updated the tests to make sure
both branches are covered.
When a base class is annotated as shared reference we can occasionally
infer that the derived types also need to be shared references.
Unfortunately, we did not generate the correct code for some of those
scenarios. When the reference counted base is not at the offset zero we
need to do offset adjustments before we pass the pointer to the
reference counting functions. We did not do those offset calculations.
I looked into implementing the codegen for the offset calculation
directly in Swift but it needed significantly more work than I
anticipated. We need to invoke the frontend to get the path to the base
class and we also need to deal with virtual inheritance, alignment and
some other considerations.
This PR ends up generating a Clang shim instead and the derived to base
conversion happens in this shim. As a result, we piggy-back on Clang
making all the correct offset calculations. This patch also had to
change how certain aspects of shared references are implemented to be
compatible with this approach:
* Instead of always looking at the base classes to querry the
retain/release operations we now propagate the corresponding
annotations once per types. This also has the beneficial effects that
we traverse the inheritance hierarchy less often.
* To generate the correct diagnostics, I reuse the result of the
refcount operation query.
* We do not want these generated functions to be inherited, so added a
set to exempt them from cloning.
* Tweaked the lookup logic for retain/release a bit as these generated
clang methods are not found by lookup. We rely on looking up the
imported methods instead.
rdar://166227787
rdar://165635002
This attribute introduces some conversions between the annotated smart
pointer type and the native swift reference type. In the future we plan
to introduce bridging so the smart pointer type can be hidden in the
signature and we can automatically convert it to the native Swift
reference type on the ABI boundaries.
This PR is using a new way to use swift_attr attributes. Instead of
doing the parsing in the clang importer it falls back to Swift's
attribute parsing and makes sure that the annotation has valid Swift
attribute syntax.
rdar://156521316
This introduces support for converting a Swift closure that captures variables from its surrounding context into an instance of `std::function`, which is useful for working with C++ APIs that use callbacks.
Each instantiation of `std::function` gets a synthesized Swift constructor that takes a Swift closure. Unlike the previous implementation, the closure is _not_ marked as `@convention(c)`. The body of the constructor is created lazily.
Under the hood, the closure is bitcast to a pair of a function pointer and a context pointer, which are then wrapped in a C++ object, `__SwiftFunctionWrapper`, that manages the lifetime of the context object via calls to `swift_retain`/`swift_release` from the copy constructor and the destructor. The `__SwiftFunctionWrapper` class is templated, and is instantiated by ClangImporter.
rdar://133777029
Generate switch-based validation for @frozen enum init?(rawValue:)
instead of using unchecked reinterpretCast. This ensures only declared
enum cases are accepted, returning nil for invalid raw values.
For non-frozen enums (NS_ENUM), preserve existing reinterpretCast
behavior for C compatibility.
Fixes#85701
We build forwarding methods to call the virtual methods. The forwarding
methods tried to copy move-only types which resulted in a compiler
crash. Now we try to detect this scenario and insert the required cast
to make sure we get a move instead.
rdar://162195228
When compiling a Swift module in incremental mode, each Swift source file is compiled into an object file
and we use linker to link them together. Because the predicate function for checking dynamic feature
availability is eagerly synthesized per compilation unit, the linker will complain about duplicated
symbols for them. Setting their visibility as private ensures that linker doesn't see them, thus addressing
the linker errors.
One workaround for this problem is to enable WMO.
rdar://164971313
For dynamic features defined from a header, we synthesize a pure Clang function to check whether the feature should
be enabled at runtime. Swift modules don't have capability to deserialize this clang predicate function, leading to
crasher as a result. This change fixes the crasher by hiding the synthesized function to be a module internal one.
rdar://164410957
Implement the @export(implementation) and @export(interface) attributes
to replace @_alwaysEmitIntoClient and @_neverEmitIntoClient. Provide a
warning + Fix-It to start staging out the very-new
@_neverEmitIntoClient. We'll hold off on pushing folks toward
@_alwaysEmitIntoClient for a little longer.
When creating a C++ method that thunks from a particular C++ derived
class to call a method on one of its base classes, we do some manual
name mangling. This name mangling did not properly capture all of the
aspects of the thunk, so it was prone to collisions.
In moving to SIL asmname, we got a different set of collisions from
the ones that existed previously. Expanding the mangling to account
for small differences (const or not) as well as the base class type
eliminates these collisions. Most of the test changes account for the
new mangling, but the member-inheritance test indicates that this
change fixes an existing miscompile as well.
We stumbled upon an old workaround that disabled the synthesis of Swift default expressions for C++ function parameters that don't have a name.
This change removes the workaround.
rdar://162310543
`span` is not available in all versions of libstd++, so make it a
conditional header. Also adds other missing c++20 headers.
Fixing this triggered an assert when importing a constant initialized
`wchar_t` variable, so that is also fixed. The reason is that `wchar_t`
is mapped to `Unicode.Scalar`, which cannot be directly initialized by
integer literals in Swift, triggering an assert when looking up the
protocol conformance for `_ExpressibleByBuiltinIntegerLiteral`.
rdar://162074714