Skip to content

Commit 57f3d23

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 57f3d23

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-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: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2403,6 +2403,17 @@ LinkInfo LinkInfo::get(const UniversalLinkageInfo &linkInfo,
24032403
if (const auto *DC = entity.getDeclContextForEmission()) {
24042404
if (const auto *MD = DC->getParentModule())
24052405
isKnownLocal = MD == swiftModule || MD->isStaticLibrary();
2406+
if (!isKnownLocal && !isDefinition) {
2407+
bool isClangImportedEntity =
2408+
isa<ClangModuleUnit>(DC->getModuleScopeContext());
2409+
// Nominal type descriptor for a type imported from a Clang module
2410+
// is always a local declaration as it's generated on demand. When WMO is
2411+
// off, it's emitted into the current file's object file. When WMO is on,
2412+
// it's emitted into one of the object files in the current module, and
2413+
// thus it's never imported from outside of the module.
2414+
if (isClangImportedEntity && entity.isNominalTypeDescriptor())
2415+
isKnownLocal = true;
2416+
}
24062417
} else if (entity.hasSILFunction()) {
24072418
// SIL serialized entities (functions, witness tables, vtables) do not have
24082419
// an associated DeclContext and are serialized into the current module. As
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 across 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)