@@ -502,54 +502,71 @@ ValueMetatypeInst *SILBuilder::createValueMetatype(SILLocation Loc,
502
502
}
503
503
504
504
// TODO: This should really be an operation on type lowering.
505
- void SILBuilder::emitShallowDestructureValueOperation (
506
- SILLocation Loc , SILValue V, llvm:: SmallVectorImpl<SILValue> &Results ) {
505
+ void SILBuilder::emitDestructureValueOperation (
506
+ SILLocation loc , SILValue v, SmallVectorImpl<SILValue> &results ) {
507
507
// Once destructure is allowed everywhere, remove the projection code.
508
508
509
509
// If we do not have a tuple or a struct, add to our results list and return.
510
- SILType Ty = V ->getType ();
511
- if (!(Ty .is <TupleType>() || Ty .getStructOrBoundGenericStruct ())) {
512
- Results .emplace_back (V );
510
+ SILType type = v ->getType ();
511
+ if (!(type .is <TupleType>() || type .getStructOrBoundGenericStruct ())) {
512
+ results .emplace_back (v );
513
513
return ;
514
514
}
515
515
516
516
// Otherwise, we want to destructure add the destructure and return.
517
517
if (getFunction ().hasOwnership ()) {
518
- auto *DI = emitDestructureValueOperation (Loc, V );
519
- copy (DI ->getResults (), std::back_inserter (Results ));
518
+ auto *i = emitDestructureValueOperation (loc, v );
519
+ copy (i ->getResults (), std::back_inserter (results ));
520
520
return ;
521
521
}
522
522
523
523
// In non qualified ownership SIL, drop back to using projection code.
524
- llvm:: SmallVector<Projection, 16 > Projections ;
525
- Projection::getFirstLevelProjections (V ->getType (), getModule (), Projections );
526
- transform (Projections , std::back_inserter (Results ),
527
- [&](const Projection &P ) -> SILValue {
528
- return P .createObjectProjection (*this , Loc, V ).get ();
524
+ SmallVector<Projection, 16 > projections ;
525
+ Projection::getFirstLevelProjections (v ->getType (), getModule (), projections );
526
+ transform (projections , std::back_inserter (results ),
527
+ [&](const Projection &p ) -> SILValue {
528
+ return p .createObjectProjection (*this , loc, v ).get ();
529
529
});
530
530
}
531
531
532
532
// TODO: Can we put this on type lowering? It would take a little bit of work
533
533
// since we would need to be able to handle aggregate trivial types which is not
534
534
// represented today in TypeLowering.
535
- void SILBuilder::emitShallowDestructureAddressOperation (
536
- SILLocation Loc , SILValue V, llvm:: SmallVectorImpl<SILValue> &Results ) {
535
+ void SILBuilder::emitDestructureAddressOperation (
536
+ SILLocation loc , SILValue v, SmallVectorImpl<SILValue> &results ) {
537
537
538
538
// If we do not have a tuple or a struct, add to our results list.
539
- SILType Ty = V ->getType ();
540
- if (!(Ty .is <TupleType>() || Ty .getStructOrBoundGenericStruct ())) {
541
- Results .emplace_back (V );
539
+ SILType type = v ->getType ();
540
+ if (!(type .is <TupleType>() || type .getStructOrBoundGenericStruct ())) {
541
+ results .emplace_back (v );
542
542
return ;
543
543
}
544
544
545
- llvm:: SmallVector<Projection, 16 > Projections ;
546
- Projection::getFirstLevelProjections (V ->getType (), getModule (), Projections );
547
- transform (Projections , std::back_inserter (Results ),
548
- [&](const Projection &P ) -> SILValue {
549
- return P .createAddressProjection (*this , Loc, V ).get ();
545
+ SmallVector<Projection, 16 > projections ;
546
+ Projection::getFirstLevelProjections (v ->getType (), getModule (), projections );
547
+ transform (projections , std::back_inserter (results ),
548
+ [&](const Projection &p ) -> SILValue {
549
+ return p .createAddressProjection (*this , loc, v ).get ();
550
550
});
551
551
}
552
552
553
+ void SILBuilder::emitDestructureValueOperation (
554
+ SILLocation loc, SILValue operand,
555
+ function_ref<void (unsigned , SILValue)> func) {
556
+ // Do a quick check to see if we have a tuple without elements. In that
557
+ // case, bail early since we are not going to ever invoke Func.
558
+ if (auto tupleType = operand->getType ().castTo <TupleType>())
559
+ if (0 == tupleType->getNumElements ())
560
+ return ;
561
+
562
+ SmallVector<SILValue, 8 > results;
563
+ emitDestructureValueOperation (loc, operand, results);
564
+
565
+ for (auto p : llvm::enumerate (results)) {
566
+ func (p.index (), p.value ());
567
+ }
568
+ }
569
+
553
570
DebugValueInst *SILBuilder::createDebugValue (SILLocation Loc, SILValue src,
554
571
SILDebugVariable Var) {
555
572
assert (isLoadableOrOpaque (src->getType ()));
0 commit comments