Skip to content

[SR-12614] [C++] Add support for default arguments in C++ function calls #55058

@swift-ci

Description

@swift-ci
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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.c++ interopFeature: Interoperability with C++compilerThe Swift compiler itself

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions