-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Previous ID | SR-12614 |
Radar | rdar://problem/62202405 |
Original Reporter | martinboehme (JIRA User) |
Type | Bug |
Additional Detail from JIRA
Votes | 0 |
Component/s | Compiler |
Labels | Bug, CxxInterop |
Assignee | None |
Priority | Medium |
md5: 3903c8bd8190fb3dcf0ec04aae1d1a2f
Issue Description:
Currently, functions with default arguments are imported, but the default arguments themselves are not, making it necessary to specify all of the parameters explicitly. For example, the C++ function
void foo(int a, int b = 42);
is imported as
func foo(_ a: CInt, _ b: CInt)
We should add support for default arguments, and the C++ interoperability manifesto should be extended to describe this.
The C++ expression for a default argument would be turned into an opaque default argument generator function.
In addition, we would need to make sure the default argument is represented correctly when pretty-printing the module API. This is actually not too hard because Swift's module format does not support serializing expressions; the expression for a default argument is simply serialized as a string. We can therefore, in principle, just put the textual expression for the C++ default argument in this string.
We should take some care with how we do this though because C++ default arguments can contain complex C++ expressions, which in general don't make sense in Swift source code. We therefore probably want to print the expression inside a comment, something like this:
func foo(_ a: CInt, _b: CInt = default /* some(complexCxxExpression()) */)
(The default
is just pseudo-syntax to have something that looks like a Swift default argument.)
Optionally, to improve quality-of-implementation, we could detect cases where the default argument is a simple expression (e.g. an integer literal) and represent it without a comment:
func foo(_ a: CInt, _b: CInt = 42)
One case we should make sure to test is when a C++ default argument is initialized with the result of calling an inline function:
inline int inlineFunc() {
return 42;
}
int foo(int a, int b = inlineFunc());
We need to make sure in this case that inlineFunc()
is emitted by IRGen. See #31035 for a similar case concerning transitively called inline functions.