@@ -159,7 +159,8 @@ class FunctionLivenessComputation {
159
159
auto methodWitness = entry.getMethodWitness ();
160
160
auto *fd = cast<AbstractFunctionDecl>(methodWitness.Requirement .
161
161
getDecl ());
162
- assert (fd == getBase (fd) && " key in witness table is overridden" );
162
+ assert (fd == getBaseMethod (fd) &&
163
+ " key in witness table is overridden" );
163
164
SILFunction *F = methodWitness.Witness ;
164
165
if (F) {
165
166
MethodInfo *MI = getMethodInfo (fd, /* isWitnessMethod*/ true );
@@ -324,15 +325,6 @@ class FunctionLivenessComputation {
324
325
}
325
326
}
326
327
327
- // / Gets the base implementation of a method.
328
- // / We always use the most overridden function to describe a method.
329
- AbstractFunctionDecl *getBase (AbstractFunctionDecl *FD) {
330
- while (FD->getOverriddenDecl ()) {
331
- FD = FD->getOverriddenDecl ();
332
- }
333
- return FD;
334
- }
335
-
336
328
// / Scans all references inside a function.
337
329
void scanFunction (SILFunction *F) {
338
330
@@ -342,12 +334,12 @@ class FunctionLivenessComputation {
342
334
for (SILBasicBlock &BB : *F) {
343
335
for (SILInstruction &I : BB) {
344
336
if (auto *WMI = dyn_cast<WitnessMethodInst>(&I)) {
345
- auto *funcDecl = getBase (
337
+ auto *funcDecl = getBaseMethod (
346
338
cast<AbstractFunctionDecl>(WMI->getMember ().getDecl ()));
347
339
MethodInfo *mi = getMethodInfo (funcDecl, /* isWitnessTable*/ true );
348
340
ensureAliveProtocolMethod (mi);
349
341
} else if (auto *MI = dyn_cast<MethodInst>(&I)) {
350
- auto *funcDecl = getBase (
342
+ auto *funcDecl = getBaseMethod (
351
343
cast<AbstractFunctionDecl>(MI->getMember ().getDecl ()));
352
344
assert (MI->getNumOperands () - MI->getNumTypeDependentOperands () == 1
353
345
&& " method insts except witness_method must have 1 operand" );
@@ -474,7 +466,8 @@ class DeadFunctionElimination : FunctionLivenessComputation {
474
466
continue ;
475
467
}
476
468
SILFunction *F = entry.Implementation ;
477
- auto *fd = getBase (cast<AbstractFunctionDecl>(entry.Method .getDecl ()));
469
+ auto *fd = getBaseMethod (cast<AbstractFunctionDecl>(
470
+ entry.Method .getDecl ()));
478
471
MethodInfo *mi = getMethodInfo (fd, /* isWitnessTable*/ false );
479
472
mi->addClassMethodImpl (F, vTable.getClass ());
480
473
}
@@ -490,7 +483,8 @@ class DeadFunctionElimination : FunctionLivenessComputation {
490
483
auto methodWitness = entry.getMethodWitness ();
491
484
auto *fd = cast<AbstractFunctionDecl>(methodWitness.Requirement .
492
485
getDecl ());
493
- assert (fd == getBase (fd) && " key in witness table is overridden" );
486
+ assert (fd == getBaseMethod (fd) &&
487
+ " key in witness table is overridden" );
494
488
SILFunction *F = methodWitness.Witness ;
495
489
if (!F)
496
490
continue ;
@@ -533,12 +527,14 @@ class DeadFunctionElimination : FunctionLivenessComputation {
533
527
}
534
528
535
529
SILFunction *F = entry.Implementation ;
536
- auto *fd = getBase (cast<AbstractFunctionDecl>(entry.Method .getDecl ()));
530
+ auto *fd = getBaseMethod (cast<AbstractFunctionDecl>(
531
+ entry.Method .getDecl ()));
537
532
538
533
if (// We also have to check the method declaration's access level.
539
534
// Needed if it's a public base method declared in another
540
535
// compilation unit (for this we have no SILFunction).
541
536
isVisibleExternally (fd)
537
+ || Module->isExternallyVisibleDecl (fd)
542
538
// Declarations are always accessible externally, so they are alive.
543
539
|| !F->isDefinition ()) {
544
540
MethodInfo *mi = getMethodInfo (fd, /* isWitnessTable*/ false );
@@ -550,24 +546,27 @@ class DeadFunctionElimination : FunctionLivenessComputation {
550
546
// Check witness table methods.
551
547
for (SILWitnessTable &WT : Module->getWitnessTableList ()) {
552
548
ProtocolConformance *Conf = WT.getConformance ();
553
- if ( isVisibleExternally (Conf->getProtocol ())) {
554
- // The witness table is visible from "outside". Therefore all methods
555
- // might be called and we mark all methods as alive.
556
- for (const SILWitnessTable::Entry &entry : WT.getEntries ()) {
557
- if (entry.getKind () != SILWitnessTable::Method)
558
- continue ;
549
+ bool tableExternallyVisible = isVisibleExternally (Conf->getProtocol ());
550
+ // The witness table is visible from "outside". Therefore all methods
551
+ // might be called and we mark all methods as alive.
552
+ for (const SILWitnessTable::Entry &entry : WT.getEntries ()) {
553
+ if (entry.getKind () != SILWitnessTable::Method)
554
+ continue ;
559
555
560
- auto methodWitness = entry.getMethodWitness ();
561
- auto *fd = cast<AbstractFunctionDecl>(methodWitness.Requirement .
562
- getDecl ());
563
- assert (fd == getBase (fd) && " key in witness table is overridden" );
564
- SILFunction *F = methodWitness.Witness ;
565
- if (!F)
566
- continue ;
556
+ auto methodWitness = entry.getMethodWitness ();
557
+ auto *fd = cast<AbstractFunctionDecl>(methodWitness.Requirement .
558
+ getDecl ());
559
+ assert (fd == getBaseMethod (fd) &&
560
+ " key in witness table is overridden" );
561
+ SILFunction *F = methodWitness.Witness ;
562
+ if (!F)
563
+ continue ;
567
564
568
- MethodInfo *mi = getMethodInfo (fd, /* isWitnessTable*/ true );
569
- ensureAliveProtocolMethod (mi);
570
- }
565
+ if (!tableExternallyVisible && !Module->isExternallyVisibleDecl (fd))
566
+ continue ;
567
+
568
+ MethodInfo *mi = getMethodInfo (fd, /* isWitnessTable*/ true );
569
+ ensureAliveProtocolMethod (mi);
571
570
}
572
571
573
572
// We don't do dead witness table elimination right now. So we assume
@@ -588,7 +587,7 @@ class DeadFunctionElimination : FunctionLivenessComputation {
588
587
auto *fd =
589
588
cast<AbstractFunctionDecl>(
590
589
entry.getMethodWitness ().Requirement .getDecl ());
591
- assert (fd == getBase (fd) &&
590
+ assert (fd == getBaseMethod (fd) &&
592
591
" key in default witness table is overridden" );
593
592
SILFunction *F = entry.getMethodWitness ().Witness ;
594
593
if (!F)
0 commit comments