Skip to content

Commit 33e41f1

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 33e41f1

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-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: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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+
// FIXME: Windows test can be enabled once merge-modules step is removed from the old driver,
14+
// or the Windows CI starts to use the new driver to compile the compiler.
15+
// The windows toolchains still use the new driver so the CI failure worked
16+
// around here should not affect users on Windows.
17+
// UNSUPPORTED: OS=windows-msvc
18+
19+
//--- main.swift
20+
import DefaultArguments
21+
public func foo() {
22+
let _ = isZero()
23+
}
24+
foo()
25+
bar()
26+
baz()
27+
28+
//--- b.swift
29+
import DefaultArguments
30+
public func bar() {
31+
let _ = isZero()
32+
}
33+
34+
//--- c.swift
35+
import DefaultArguments
36+
public func baz() {
37+
let _ = isZero(123)
38+
}
39+
40+
//--- uses-library.swift
41+
import DefaultArguments
42+
import BarLibrary
43+
44+
let _ = isZero()
45+
bar()
46+
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)