|
28 | 28 | #include "swift/SIL/SILModule.h"
|
29 | 29 | #include "swift/SIL/SILVTableVisitor.h"
|
30 | 30 | #include "swift/SIL/SILWitnessTable.h"
|
| 31 | +#include "swift/SIL/SILWitnessVisitor.h" |
31 | 32 | #include "swift/SIL/TypeLowering.h"
|
32 | 33 | #include "llvm/ADT/StringSet.h"
|
33 | 34 | #include "llvm/Support/Error.h"
|
@@ -280,7 +281,7 @@ void TBDGenVisitor::visitAbstractStorageDecl(AbstractStorageDecl *ASD) {
|
280 | 281 |
|
281 | 282 | // Explicitly look at each accessor here: see visitAccessorDecl.
|
282 | 283 | for (auto accessor : ASD->getAllAccessors()) {
|
283 |
| - visitAbstractFunctionDecl(accessor); |
| 284 | + visitFuncDecl(accessor); |
284 | 285 | }
|
285 | 286 | }
|
286 | 287 |
|
@@ -365,16 +366,8 @@ void TBDGenVisitor::visitClassDecl(ClassDecl *CD) {
|
365 | 366 |
|
366 | 367 | // Some members of classes get extra handling, beyond members of struct/enums,
|
367 | 368 | // so let's walk over them manually.
|
368 |
| - for (auto *member : CD->getMembers()) { |
369 |
| - auto value = dyn_cast<ValueDecl>(member); |
370 |
| - if (!value) |
371 |
| - continue; |
372 |
| - |
373 |
| - auto var = dyn_cast<VarDecl>(value); |
374 |
| - auto hasFieldOffset = var && var->hasStorage() && !var->isStatic(); |
375 |
| - if (hasFieldOffset) |
376 |
| - addSymbol(LinkEntity::forFieldOffset(var)); |
377 |
| - } |
| 369 | + for (auto *var : CD->getStoredProperties()) |
| 370 | + addSymbol(LinkEntity::forFieldOffset(var)); |
378 | 371 |
|
379 | 372 | visitNominalTypeDecl(CD);
|
380 | 373 |
|
@@ -465,28 +458,6 @@ void TBDGenVisitor::visitExtensionDecl(ExtensionDecl *ED) {
|
465 | 458 | visit(member);
|
466 | 459 | }
|
467 | 460 |
|
468 |
| -/// Determine whether the protocol descriptor for the given protocol will |
469 |
| -/// contain any protocol requirements. |
470 |
| -static bool protocolDescriptorHasRequirements(ProtocolDecl *proto) { |
471 |
| - if (!proto->getRequirementSignature().empty()) |
472 |
| - return true; |
473 |
| - |
474 |
| - for (auto *member : proto->getMembers()) { |
475 |
| - if (auto func = dyn_cast<AbstractFunctionDecl>(member)) { |
476 |
| - if (SILDeclRef::requiresNewWitnessTableEntry(func)) |
477 |
| - return true; |
478 |
| - } |
479 |
| - |
480 |
| - if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) { |
481 |
| - if (assocType->getOverriddenDecls().empty()) { |
482 |
| - return true; |
483 |
| - } |
484 |
| - } |
485 |
| - } |
486 |
| - |
487 |
| - return false; |
488 |
| -} |
489 |
| - |
490 | 461 | #ifndef NDEBUG
|
491 | 462 | static bool isValidProtocolMemberForTBDGen(const Decl *D) {
|
492 | 463 | switch (D->getKind()) {
|
@@ -530,45 +501,45 @@ void TBDGenVisitor::visitProtocolDecl(ProtocolDecl *PD) {
|
530 | 501 | if (!PD->isObjC()) {
|
531 | 502 | addSymbol(LinkEntity::forProtocolDescriptor(PD));
|
532 | 503 |
|
533 |
| - // If there are any requirements, emit a requirements base descriptor. |
534 |
| - if (protocolDescriptorHasRequirements(PD)) |
535 |
| - addProtocolRequirementsBaseDescriptor(PD); |
536 |
| - |
537 |
| - for (const auto &req : PD->getRequirementSignature()) { |
538 |
| - if (req.getKind() != RequirementKind::Conformance) |
539 |
| - continue; |
540 |
| - |
541 |
| - if (req.getFirstType()->isEqual(PD->getSelfInterfaceType())) { |
542 |
| - BaseConformance conformance( |
543 |
| - PD, |
544 |
| - req.getSecondType()->castTo<ProtocolType>()->getDecl()); |
545 |
| - addBaseConformanceDescriptor(conformance); |
546 |
| - } else { |
547 |
| - AssociatedConformance conformance( |
548 |
| - PD, |
549 |
| - req.getFirstType()->getCanonicalType(), |
550 |
| - req.getSecondType()->castTo<ProtocolType>()->getDecl()); |
551 |
| - addAssociatedConformanceDescriptor(conformance); |
552 |
| - } |
553 |
| - } |
| 504 | + struct WitnessVisitor : public SILWitnessVisitor<WitnessVisitor> { |
| 505 | + TBDGenVisitor &TBD; |
| 506 | + ProtocolDecl *PD; |
554 | 507 |
|
555 |
| - for (auto *member : PD->getMembers()) { |
556 |
| - if (PD->isResilient()) { |
557 |
| - if (auto *funcDecl = dyn_cast<AbstractFunctionDecl>(member)) { |
558 |
| - if (SILDeclRef::requiresNewWitnessTableEntry(funcDecl)) { |
559 |
| - addDispatchThunk(SILDeclRef(funcDecl)); |
560 |
| - addMethodDescriptor(SILDeclRef(funcDecl)); |
561 |
| - } |
| 508 | + public: |
| 509 | + WitnessVisitor(TBDGenVisitor &TBD, ProtocolDecl *PD) |
| 510 | + : TBD(TBD), PD(PD) {} |
| 511 | + |
| 512 | + void addMethod(SILDeclRef declRef) { |
| 513 | + if (PD->isResilient()) { |
| 514 | + TBD.addDispatchThunk(declRef); |
| 515 | + TBD.addMethodDescriptor(declRef); |
562 | 516 | }
|
563 | 517 | }
|
564 | 518 |
|
565 |
| - // Always produce associated type descriptors, because they can |
566 |
| - // be referenced by generic signatures. |
567 |
| - if (auto *assocType = dyn_cast<AssociatedTypeDecl>(member)) { |
568 |
| - if (assocType->getOverriddenDecls().empty()) |
569 |
| - addAssociatedTypeDescriptor(assocType); |
| 519 | + void addAssociatedType(AssociatedType associatedType) { |
| 520 | + TBD.addAssociatedTypeDescriptor(associatedType.getAssociation()); |
570 | 521 | }
|
571 |
| - } |
| 522 | + |
| 523 | + void addProtocolConformanceDescriptor() { |
| 524 | + TBD.addProtocolRequirementsBaseDescriptor(PD); |
| 525 | + } |
| 526 | + |
| 527 | + void addOutOfLineBaseProtocol(ProtocolDecl *proto) { |
| 528 | + TBD.addBaseConformanceDescriptor(BaseConformance(PD, proto)); |
| 529 | + } |
| 530 | + |
| 531 | + void addAssociatedConformance(AssociatedConformance associatedConf) { |
| 532 | + TBD.addAssociatedConformanceDescriptor(associatedConf); |
| 533 | + } |
| 534 | + |
| 535 | + void addPlaceholder(MissingMemberDecl *decl) {} |
| 536 | + |
| 537 | + void doIt() { |
| 538 | + visitProtocolDecl(PD); |
| 539 | + } |
| 540 | + }; |
| 541 | + |
| 542 | + WitnessVisitor(*this, PD).doIt(); |
572 | 543 |
|
573 | 544 | // Include the self-conformance.
|
574 | 545 | addConformances(PD);
|
|
0 commit comments