Skip to content

Commit 7896558

Browse files
committed
[IRGen] Give property behavior conformances protocol conformance descriptors.
Protocol conformance descriptors are recorded in witness tables and are needed to evaluate associated type witnesses. Start creating them for property behavior conformances, but don’t put them in the section used for reflection.
1 parent a23135a commit 7896558

File tree

2 files changed

+22
-18
lines changed

2 files changed

+22
-18
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -680,10 +680,7 @@ void IRGenModule::emitRuntimeRegistration() {
680680
}
681681

682682
// Register Swift protocol conformances if we added any.
683-
if (!ProtocolConformances.empty()) {
684-
685-
llvm::Constant *conformances = emitProtocolConformances();
686-
683+
if (llvm::Constant *conformances = emitProtocolConformances()) {
687684
llvm::Constant *beginIndices[] = {
688685
llvm::ConstantInt::get(Int32Ty, 0),
689686
llvm::ConstantInt::get(Int32Ty, 0),
@@ -2461,18 +2458,29 @@ void IRGenModule::addProtocolConformance(
24612458

24622459
/// Emit the protocol conformance list and return it.
24632460
llvm::Constant *IRGenModule::emitProtocolConformances() {
2464-
// Do nothing if the list is empty.
2465-
if (ProtocolConformances.empty())
2461+
// Emit the conformances.
2462+
bool anyReflectedConformances = false;
2463+
for (auto *conformance : ProtocolConformances) {
2464+
// Emit the protocol conformance now.
2465+
emitProtocolConformance(conformance);
2466+
2467+
if (conformance->isBehaviorConformance())
2468+
continue;
2469+
2470+
anyReflectedConformances = true;
2471+
}
2472+
2473+
if (!anyReflectedConformances)
24662474
return nullptr;
24672475

24682476
// Define the global variable for the conformance list.
2469-
24702477
ConstantInitBuilder builder(*this);
24712478
auto descriptorArray = builder.beginArray(RelativeAddressTy);
24722479

24732480
for (auto *conformance : ProtocolConformances) {
2474-
// Emit the protocol conformance now.
2475-
emitProtocolConformance(conformance);
2481+
// Behavior conformances cannot be reflected.
2482+
if (conformance->isBehaviorConformance())
2483+
continue;
24762484

24772485
auto entity = LinkEntity::forProtocolConformanceDescriptor(conformance);
24782486
auto descriptor =

lib/IRGen/GenProto.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,13 +1267,9 @@ llvm::Value *uniqueForeignWitnessTableRef(IRGenFunction &IGF,
12671267
/// Add reference to the protocol conformance descriptor that generated
12681268
/// this table.
12691269
void addProtocolConformanceDescriptor() {
1270-
if (Conformance.isBehaviorConformance()) {
1271-
Table.addNullPointer(IGM.Int8PtrTy);
1272-
} else {
1273-
auto descriptor =
1274-
IGM.getAddrOfProtocolConformanceDescriptor(&Conformance);
1275-
Table.addBitCast(descriptor, IGM.Int8PtrTy);
1276-
}
1270+
auto descriptor =
1271+
IGM.getAddrOfProtocolConformanceDescriptor(&Conformance);
1272+
Table.addBitCast(descriptor, IGM.Int8PtrTy);
12771273
}
12781274

12791275
/// A base protocol is witnessed by a pointer to the conformance
@@ -2483,12 +2479,12 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
24832479
// Always emit an accessor function.
24842480
wtableBuilder.buildAccessFunction(global);
24852481

2482+
addProtocolConformance(conf);
2483+
24862484
// Behavior conformances can't be reflected.
24872485
if (conf->isBehaviorConformance())
24882486
return;
24892487

2490-
addProtocolConformance(conf);
2491-
24922488
// Trigger the lazy emission of the foreign type metadata.
24932489
CanType conformingType = conf->getType()->getCanonicalType();
24942490
if (requiresForeignTypeMetadata(conformingType)) {

0 commit comments

Comments
 (0)