Skip to content

Commit 77ea0d5

Browse files
authored
Merge pull request swiftlang#18637 from jckarter/share-c-and-uninhabited-enum-value-witness
[WIP] IRGen: Use prefab value witness tables for uninhabited and @objc enums.
2 parents 88582db + 8eee14d commit 77ea0d5

File tree

3 files changed

+23
-8
lines changed

3 files changed

+23
-8
lines changed

lib/IRGen/GenValueWitness.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -983,18 +983,28 @@ getAddrOfKnownValueWitnessTable(IRGenModule &IGM, CanType type) {
983983

984984
if (auto nom = type->getAnyNominal()) {
985985
// TODO: Generic metadata patterns relative-reference their VWT, which won't
986-
// work if it's in a different module without supporting indirection through
987-
// the GOT.
986+
// work if the VWT is in a different module without supporting indirection
987+
// through the GOT.
988988
if (nom->isGenericContext())
989989
return nullptr;
990-
// TODO: Enums need additional value witnesses for their tag manipulation.
991-
if (isa<EnumDecl>(nom))
992-
return nullptr;
990+
// TODO: Non-C enums have extra inhabitants and also need additional value
991+
// witnesses for their tag manipulation (except when they're empty, in
992+
// which case values never exist to witness).
993+
if (auto enumDecl = dyn_cast<EnumDecl>(nom))
994+
if (!enumDecl->isObjC() && !type->isUninhabited())
995+
return nullptr;
993996
}
994-
997+
998+
auto &C = IGM.Context;
999+
9951000
type = getFormalTypeInContext(type);
9961001

9971002
auto &ti = IGM.getTypeInfoForUnlowered(AbstractionPattern::getOpaque(), type);
1003+
1004+
// Empty types can use empty tuple witnesses.
1005+
if (ti.isKnownEmpty(ResilienceExpansion::Maximal))
1006+
return IGM.getAddrOfValueWitnessTable(TupleType::getEmpty(C));
1007+
9981008
// We only have witnesses for fixed type info.
9991009
auto *fixedTI = dyn_cast<FixedTypeInfo>(&ti);
10001010
if (!fixedTI)
@@ -1003,7 +1013,6 @@ getAddrOfKnownValueWitnessTable(IRGenModule &IGM, CanType type) {
10031013
CanType witnessSurrogate;
10041014

10051015
// Handle common POD type layouts.
1006-
auto &C = type->getASTContext();
10071016
ReferenceCounting refCounting;
10081017
if (fixedTI->isPOD(ResilienceExpansion::Maximal)
10091018
&& fixedTI->getFixedExtraInhabitantCount(IGM) == 0) {

test/IRGen/empty_enum.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: %target-swift-frontend -primary-file %s -emit-ir | %FileCheck %s
2+
3+
// CHECK: @"$S10empty_enum6JamaisOMf" =
4+
// CHECK-SAME: @"$SytWV"
5+
6+
enum Jamais {}

test/IRGen/objc_ns_enum.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
import Foundation
99
import gizmo
1010

11-
// CHECK: @"$SSo16NSRuncingOptionsVWV" = linkonce_odr hidden constant
1211
// CHECK: @"$SSo16NSRuncingOptionsVMn" = linkonce_odr hidden constant
1312
// CHECK: @"$SSo16NSRuncingOptionsVN" = linkonce_odr hidden constant
13+
// CHECK-SAME: @"$SBi{{[0-9]+}}_WV"
1414
// CHECK: @"$SSo16NSRuncingOptionsVSQSCMc" = linkonce_odr hidden constant %swift.protocol_conformance_descriptor { {{.*}}@"$SSo16NSRuncingOptionsVSQSCWa
1515
// CHECK: @"$SSo28NeverActuallyMentionedByNameVSQSCWp" = linkonce_odr hidden constant
1616

0 commit comments

Comments
 (0)