@@ -262,7 +262,7 @@ void SILGenFunction::emitDeallocatingMoveOnlyDestructor(DestructorDecl *dd) {
262262 // Clean up our members, consuming our +1 self value as we do it.
263263 emitMoveOnlyMemberDestruction (selfValue,
264264 dd->getDeclContext ()->getSelfNominalTypeDecl (),
265- cleanupLoc, nullptr );
265+ cleanupLoc);
266266
267267 // Return.
268268 B.createReturn (loc, emitEmptyTuple (loc));
@@ -497,113 +497,59 @@ void SILGenFunction::emitClassMemberDestruction(ManagedValue selfValue,
497497
498498void SILGenFunction::emitMoveOnlyMemberDestruction (SILValue selfValue,
499499 NominalTypeDecl *nom,
500- CleanupLocation cleanupLoc,
501- SILBasicBlock *finishBB) {
502- // drop_deinit must be used to invalidate any user-defined struct/enum deinit
503- // before the individual members can be destroyed.
500+ CleanupLocation cleanupLoc) {
501+ // drop_deinit invalidates any user-defined struct/enum deinit
502+ // before the individual members are destroyed.
504503 selfValue = B.createDropDeinit (cleanupLoc, selfValue);
505- if (selfValue->getType ().isAddress ()) {
506- if (auto *structDecl = dyn_cast<StructDecl>(nom)) {
507- for (VarDecl *vd : nom->getStoredProperties ()) {
508- const TypeLowering &ti = getTypeLowering (vd->getType ());
509- if (ti.isTrivial ())
510- continue ;
511-
512- SILValue addr = B.createStructElementAddr (
513- cleanupLoc, selfValue, vd, ti.getLoweredType ().getAddressType ());
514- addr = B.createBeginAccess (cleanupLoc, addr, SILAccessKind::Deinit,
515- SILAccessEnforcement::Static,
516- false /* noNestedConflict*/ ,
517- false /* fromBuiltin*/ );
518- B.createDestroyAddr (cleanupLoc, addr);
519- B.createEndAccess (cleanupLoc, addr, false /* is aborting*/ );
520- }
521- } else {
522- auto *origBlock = B.getInsertionBB ();
523- auto *enumDecl = cast<EnumDecl>(nom);
524- SmallVector<std::pair<EnumElementDecl *, SILBasicBlock *>, 8 >
525- caseCleanups;
526- auto *contBlock = createBasicBlock ();
527-
528- for (auto *enumElt : enumDecl->getAllElements ()) {
529- auto *enumBlock = createBasicBlock ();
530- SILBuilder builder (enumBlock, enumBlock->begin ());
531-
532- if (enumElt->hasAssociatedValues ()) {
533- auto *take = builder.createUncheckedTakeEnumDataAddr (
534- cleanupLoc, selfValue, enumElt);
535- builder.createDestroyAddr (cleanupLoc, take);
536- }
537-
538- // Branch to the continue trampoline block.
539- builder.createBranch (cleanupLoc, contBlock);
540- caseCleanups.emplace_back (enumElt, enumBlock);
541-
542- // Set the insertion point to after this enum block so we insert the
543- // next new block after this block.
544- B.setInsertionPoint (enumBlock);
545- }
504+ if (selfValue->getType ().isObject ()) {
505+ // A destroy value that uses the result of a drop_deinit implicitly performs
506+ // memberwise destruction.
507+ B.emitDestroyValueOperation (cleanupLoc, selfValue);
508+ return ;
509+ }
510+ if (auto *structDecl = dyn_cast<StructDecl>(nom)) {
511+ for (VarDecl *vd : nom->getStoredProperties ()) {
512+ const TypeLowering &ti = getTypeLowering (vd->getType ());
513+ if (ti.isTrivial ())
514+ continue ;
546515
547- B.setInsertionPoint (origBlock);
548- B.createSwitchEnumAddr (cleanupLoc, selfValue, nullptr , caseCleanups);
549- B.setInsertionPoint (contBlock);
516+ SILValue addr = B.createStructElementAddr (
517+ cleanupLoc, selfValue, vd, ti.getLoweredType ().getAddressType ());
518+ addr = B.createBeginAccess (
519+ cleanupLoc, addr, SILAccessKind::Deinit, SILAccessEnforcement::Static,
520+ false /* noNestedConflict*/ , false /* fromBuiltin*/ );
521+ B.createDestroyAddr (cleanupLoc, addr);
522+ B.createEndAccess (cleanupLoc, addr, false /* is aborting*/ );
550523 }
551524 } else {
552- if (auto *sd = dyn_cast<StructDecl>(nom)) {
553- if (llvm::any_of (sd->getStoredProperties (),
554- [&](VarDecl *vd) {
555- auto &lowering = getTypeLowering (vd->getType ());
556- return !lowering.isTrivial ();
557- })) {
558- auto *d = B.createDestructureStruct (cleanupLoc, selfValue,
559- OwnershipKind::Owned);
560- for (auto result : d->getResults ()) {
561- B.emitDestroyValueOperation (cleanupLoc, result);
562- }
563- } else {
564- // If we only contain trivial uses, we don't have anything to cleanup,
565- // so just insert an end_lifetime.
566- B.createEndLifetime (cleanupLoc, selfValue);
525+ auto *origBlock = B.getInsertionBB ();
526+ auto *enumDecl = cast<EnumDecl>(nom);
527+ SmallVector<std::pair<EnumElementDecl *, SILBasicBlock *>, 8 > caseCleanups;
528+ auto *contBlock = createBasicBlock ();
529+
530+ for (auto *enumElt : enumDecl->getAllElements ()) {
531+ auto *enumBlock = createBasicBlock ();
532+ SILBuilder builder (enumBlock, enumBlock->begin ());
533+
534+ if (enumElt->hasAssociatedValues ()) {
535+ auto *take = builder.createUncheckedTakeEnumDataAddr (
536+ cleanupLoc, selfValue, enumElt);
537+ builder.createDestroyAddr (cleanupLoc, take);
567538 }
568- } else {
569- auto *origBlock = B.getInsertionBB ();
570- auto *enumDecl = dyn_cast<EnumDecl>(nom);
571- SmallVector<std::pair<EnumElementDecl *, SILBasicBlock *>, 8 >
572- caseCleanups;
573- auto *contBlock = createBasicBlock ();
574-
575- for (auto *enumElt : enumDecl->getAllElements ()) {
576- auto *enumBlock = createBasicBlock ();
577- SILBuilder builder (enumBlock, enumBlock->begin ());
578-
579- if (enumElt->hasAssociatedValues ()) {
580- auto caseType = selfValue->getType ().getEnumElementType (
581- enumElt, enumBlock->getParent ());
582- auto *phiArg =
583- enumBlock->createPhiArgument (caseType, OwnershipKind::Owned);
584- builder.emitDestroyValueOperation (cleanupLoc, phiArg);
585- }
586539
587- // Branch to the continue trampoline block.
588- builder.createBranch (cleanupLoc, contBlock);
589- caseCleanups.emplace_back (enumElt, enumBlock);
540+ // Branch to the continue trampoline block.
541+ builder.createBranch (cleanupLoc, contBlock);
542+ caseCleanups.emplace_back (enumElt, enumBlock);
590543
591- // Set the insertion point to after this enum block so we insert the
592- // next new block after this block.
593- B.setInsertionPoint (enumBlock);
594- }
595-
596- B.setInsertionPoint (origBlock);
597- B.createSwitchEnum (cleanupLoc, selfValue, nullptr , caseCleanups);
598- B.setInsertionPoint (contBlock);
544+ // Set the insertion point to after this enum block so we insert the
545+ // next new block after this block.
546+ B.setInsertionPoint (enumBlock);
599547 }
600- }
601548
602- if (finishBB)
603- B.createBranch (cleanupLoc, finishBB);
604-
605- if (finishBB)
606- B.emitBlock (finishBB);
549+ B.setInsertionPoint (origBlock);
550+ B.createSwitchEnumAddr (cleanupLoc, selfValue, nullptr , caseCleanups);
551+ B.setInsertionPoint (contBlock);
552+ }
607553}
608554
609555void SILGenFunction::emitObjCDestructor (SILDeclRef dtor) {
0 commit comments