Skip to content

Commit 9491de4

Browse files
committed
[IRGen][WMO] type descriptors generated for an imported Clang types are always known local declarations
This fixes a LNK4217 linker warning when building code on Windows
1 parent 9071c82 commit 9491de4

File tree

3 files changed

+71
-0
lines changed

3 files changed

+71
-0
lines changed

include/swift/IRGen/Linking.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,6 +1597,9 @@ class LinkEntity {
15971597
getKind() == Kind::DispatchThunkAllocator ||
15981598
getKind() == Kind::DispatchThunkDerivative;
15991599
}
1600+
bool isNominalTypeDescriptor() const {
1601+
return getKind() == Kind::NominalTypeDescriptor;
1602+
}
16001603

16011604
/// Determine whether this entity will be weak-imported.
16021605
bool isWeakImported(ModuleDecl *module) const;

lib/IRGen/GenDecl.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2412,6 +2412,21 @@ LinkInfo LinkInfo::get(const UniversalLinkageInfo &linkInfo,
24122412
isKnownLocal = MD == swiftModule || MD->isStaticLibrary();
24132413
}
24142414

2415+
if (!isKnownLocal && !isDefinition) {
2416+
if (auto *entityDC = entity.getDeclContextForEmission()) {
2417+
bool isClangImportedEntity =
2418+
isa<ClangModuleUnit>(entityDC->getModuleScopeContext());
2419+
// Nominal type descriptor for a type imported from a Clang module
2420+
// is always a local declaration as it's generated on demand. When WMO is
2421+
// off, it's emitted into the current file's object file. When WMO is on,
2422+
// it's emitted into one of the object files in the current module, and
2423+
// thus it's never imported from outside of the module.
2424+
if (isClangImportedEntity && entity.isNominalTypeDescriptor()) {
2425+
isKnownLocal = true;
2426+
}
2427+
}
2428+
}
2429+
24152430
bool weakImported = entity.isWeakImported(swiftModule);
24162431
result.IRL = getIRLinkage(result.Name, linkInfo,
24172432
entity.getLinkage(isDefinition), isDefinition,
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -c -num-threads 1 -emit-ir -wmo -O %t/useA.swift %t/useB.swift -I %t/Inputs -o %t/useA.swift.ir -o %t/useB.swift.ir
5+
// RUN: cat %t/useB.swift.ir | %FileCheck %s
6+
7+
//--- Inputs/module.modulemap
8+
module ClangModule {
9+
header "header.h"
10+
}
11+
12+
//--- Inputs/header.h
13+
14+
struct ImportedClangType {
15+
int x;
16+
};
17+
18+
//--- useA.swift
19+
20+
import ClangModule
21+
22+
func testA<T>(_ x: T) {
23+
print(x)
24+
}
25+
26+
public func testARun() {
27+
testA(ImportedClangType(x: 0))
28+
}
29+
30+
public struct TestUseFieldA {
31+
let x: ImportedClangType = ImportedClangType()
32+
}
33+
34+
//--- useB.swift
35+
36+
import ClangModule
37+
38+
func testB<T>(_ x: T) {
39+
print(x)
40+
}
41+
42+
public func testBRun() {
43+
testB(ImportedClangType(x: 0))
44+
}
45+
46+
public struct TestUseFieldB {
47+
let x: ImportedClangType = ImportedClangType()
48+
}
49+
50+
// The type metadata emitted for TU B, refers to the metadata from TU A,
51+
// but it doesn't need to dllimport it accross the module boundary, as it's
52+
// emitted in the same module.
53+
// CHECK: @"$sSo17ImportedClangTypeVMn" = external global %swift.type_descriptor

0 commit comments

Comments
 (0)