Skip to content

Commit b2c05fc

Browse files
committed
IRGen: Use the exact traversal that clang uses to find non-runtime implied protocols
And only replace the variable inside of the clang generated protocol-refs list. This should make this resilient to mismatches in the protocol list order.
1 parent e166ec9 commit b2c05fc

File tree

1 file changed

+19
-18
lines changed

1 file changed

+19
-18
lines changed

lib/IRGen/GenObjC.cpp

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,19 @@ getProtocolRefsList(llvm::Constant *protocol) {
433433
return std::make_pair(size, protocolRefsList);
434434
}
435435

436+
static void appendNonRuntimeImpliedProtocols(
437+
clang::ObjCProtocolDecl *proto,
438+
llvm::SetVector<clang::ObjCProtocolDecl *> &nonRuntimeImpliedProtos) {
439+
440+
if (!proto->isNonRuntimeProtocol()) {
441+
nonRuntimeImpliedProtos.insert(proto->getCanonicalDecl());
442+
return;
443+
}
444+
445+
for (auto *parent : proto->protocols())
446+
appendNonRuntimeImpliedProtocols(parent, nonRuntimeImpliedProtos);
447+
}
448+
436449
// Get runtime protocol list used during emission of objective-c protocol
437450
// metadata taking non-runtime protocols into account.
438451
static std::vector<clang::ObjCProtocolDecl *>
@@ -454,23 +467,8 @@ getRuntimeProtocolList(clang::ObjCProtocolDecl::protocol_range protocols) {
454467
// Find the non-runtime implied protocols: protocols that occur in the closest
455468
// ancestry of a non-runtime protocol.
456469
llvm::SetVector<clang::ObjCProtocolDecl *> nonRuntimeImpliedProtos;
457-
std::vector<clang::ObjCProtocolDecl *> worklist;
458-
llvm::DenseSet<clang::ObjCProtocolDecl*> seen;
459470
for (auto *nonRuntimeProto : nonRuntimeProtocols) {
460-
worklist.push_back(nonRuntimeProto);
461-
while(!worklist.empty()) {
462-
auto *item = worklist.back();
463-
worklist.pop_back();
464-
if (!seen.insert(item).second)
465-
continue;
466-
467-
if (item->isNonRuntimeProtocol()) {
468-
for (auto *parent : item->protocols())
469-
worklist.push_back(parent);
470-
} else {
471-
nonRuntimeImpliedProtos.insert(item->getCanonicalDecl());
472-
}
473-
}
471+
appendNonRuntimeImpliedProtocols(nonRuntimeProto, nonRuntimeImpliedProtos);
474472
}
475473

476474
// Subtract the implied protocols of the runtime protocols and non runtime
@@ -529,8 +527,11 @@ static void updateProtocolRefs(IRGenModule &IGM,
529527
auto record = IGM.getAddrOfObjCProtocolRecord(inheritedSwiftProtocol,
530528
NotForDefinition);
531529
auto newOpd = llvm::ConstantExpr::getBitCast(record, oldVar->getType());
532-
if (newOpd != oldVar)
533-
oldVar->replaceAllUsesWith(newOpd);
530+
if (newOpd != oldVar) {
531+
oldVar->replaceUsesWithIf(newOpd, [protocol](llvm::Use &U) -> bool {
532+
return U.getUser() == getProtocolRefsList(protocol).second;
533+
});
534+
}
534535
++currentIdx;
535536
}
536537
assert(currentIdx == protocolRefsSize);

0 commit comments

Comments
 (0)