Skip to content

Commit 2b5b09a

Browse files
author
Gabor Horvath
committed
[cxx-interop] Fix duplicate symbol error with default arguments
We synthesize a Swift function that only calls a C++ funtion that produces the default argument. We produce this function for each module that imports the C++ function with the default argument. This symbol needs to be public as it is created in the context of the Clang module and used from the Swift module. To avoid the linker errors, we always emit this function into the client which is also the right thing to do as the whole body is a single function call. rdar://138513915
1 parent a28515e commit 2b5b09a

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

lib/ClangImporter/SwiftDeclSynthesizer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "SwiftDeclSynthesizer.h"
1414
#include "swift/AST/ASTMangler.h"
15+
#include "swift/AST/Attr.h"
1516
#include "swift/AST/AttrKind.h"
1617
#include "swift/AST/Builtins.h"
1718
#include "swift/AST/Decl.h"
@@ -2508,6 +2509,8 @@ SwiftDeclSynthesizer::makeDefaultArgument(const clang::ParmVarDecl *param,
25082509
ImporterImpl.ImportedHeaderUnit);
25092510
funcDecl->setBodySynthesizer(synthesizeDefaultArgumentBody, (void *)param);
25102511
funcDecl->setAccess(AccessLevel::Public);
2512+
funcDecl->getAttrs().add(new (ctx)
2513+
AlwaysEmitIntoClientAttr(/*IsImplicit=*/true));
25112514

25122515
ImporterImpl.defaultArgGenerators[param] = funcDecl;
25132516

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
// RUN: mkdir -p %t/artifacts
4+
5+
// Multiple usages in the same module.
6+
// RUN: %target-build-swift %t/main.swift %t/b.swift %t/c.swift -cxx-interoperability-mode=upcoming-swift -I %S/Inputs -o %t/artifacts/out
7+
// RUN: %empty-directory(%t/artifacts)
8+
9+
// Multiple usages across different modules.
10+
// RUN: %target-build-swift -emit-library -module-name BarLibrary -emit-module -emit-module-path %t/artifacts/BarLibrary.swiftmodule %t/b.swift %t/c.swift -cxx-interoperability-mode=upcoming-swift -I %S/Inputs -o %t/artifacts/%target-library-name(BarLibrary)
11+
// RUN: %target-build-swift %t/uses-library.swift -cxx-interoperability-mode=upcoming-swift -I %S/Inputs -I %t/artifacts -L %t/artifacts -lBarLibrary -o %t/artifacts/uses-library
12+
13+
//--- main.swift
14+
import DefaultArguments
15+
public func foo() {
16+
let _ = isZero()
17+
}
18+
foo()
19+
bar()
20+
baz()
21+
22+
//--- b.swift
23+
import DefaultArguments
24+
public func bar() {
25+
let _ = isZero()
26+
}
27+
28+
//--- c.swift
29+
import DefaultArguments
30+
public func baz() {
31+
let _ = isZero(123)
32+
}
33+
34+
//--- uses-library.swift
35+
import DefaultArguments
36+
import BarLibrary
37+
38+
let _ = isZero()
39+
bar()
40+
baz()
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Make a local copy of the environment.
2+
config.environment = dict(config.environment)
3+
4+
# FIXME: deserialization failure with the old driver in default-arguments-multifile.swift
5+
if 'SWIFT_USE_OLD_DRIVER' in config.environment: del config.environment['SWIFT_USE_OLD_DRIVER']
6+
if 'SWIFT_AVOID_WARNING_USING_OLD_DRIVER' in config.environment: del config.environment['SWIFT_AVOID_WARNING_USING_OLD_DRIVER']

0 commit comments

Comments
 (0)