@@ -433,6 +433,19 @@ getProtocolRefsList(llvm::Constant *protocol) {
433
433
return std::make_pair (size, protocolRefsList);
434
434
}
435
435
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
+
436
449
// Get runtime protocol list used during emission of objective-c protocol
437
450
// metadata taking non-runtime protocols into account.
438
451
static std::vector<clang::ObjCProtocolDecl *>
@@ -454,23 +467,8 @@ getRuntimeProtocolList(clang::ObjCProtocolDecl::protocol_range protocols) {
454
467
// Find the non-runtime implied protocols: protocols that occur in the closest
455
468
// ancestry of a non-runtime protocol.
456
469
llvm::SetVector<clang::ObjCProtocolDecl *> nonRuntimeImpliedProtos;
457
- std::vector<clang::ObjCProtocolDecl *> worklist;
458
- llvm::DenseSet<clang::ObjCProtocolDecl*> seen;
459
470
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);
474
472
}
475
473
476
474
// Subtract the implied protocols of the runtime protocols and non runtime
@@ -529,8 +527,11 @@ static void updateProtocolRefs(IRGenModule &IGM,
529
527
auto record = IGM.getAddrOfObjCProtocolRecord (inheritedSwiftProtocol,
530
528
NotForDefinition);
531
529
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
+ }
534
535
++currentIdx;
535
536
}
536
537
assert (currentIdx == protocolRefsSize);
0 commit comments