@@ -688,21 +688,22 @@ static llvm::Constant *emitEmptyTupleTypeMetadataRef(IRGenModule &IGM) {
688
688
/* Ty=*/ nullptr , fullMetadata, indices);
689
689
}
690
690
691
- // / Note that the element request will always be of a
692
- // / canResponseStatusBeIgnored() kind.
693
691
using GetElementMetadataFn =
694
- llvm::function_ref<llvm::Value * (CanType eltType,
695
- DynamicMetadataRequest eltRequest)>;
692
+ llvm::function_ref<MetadataResponse (CanType eltType,
693
+ DynamicMetadataRequest eltRequest)>;
696
694
697
695
static MetadataResponse emitTupleTypeMetadataRef (IRGenFunction &IGF,
698
696
CanTupleType type,
699
697
DynamicMetadataRequest request,
700
698
bool useLabels,
701
- GetElementMetadataFn getElementMetadata) {
702
-
703
- // FIXME: at least propagate dependency failure here.
704
- // FIXME: allow abstract creation when the runtime supports that.
705
- DynamicMetadataRequest eltRequest = MetadataState::Complete;
699
+ GetElementMetadataFn getMetadataRecursive) {
700
+ auto getElementMetadata = [&](CanType type) {
701
+ // Just request the elements to be abstract so that we can always build
702
+ // the metadata.
703
+ // TODO: if we have a collector, or if this is a blocking request, maybe
704
+ // we should build a stronger request?
705
+ return getMetadataRecursive (type, MetadataState::Abstract).getMetadata ();
706
+ };
706
707
707
708
switch (type->getNumElements ()) {
708
709
case 0 :
@@ -712,42 +713,45 @@ static MetadataResponse emitTupleTypeMetadataRef(IRGenFunction &IGF,
712
713
case 1 :
713
714
// For metadata purposes, we consider a singleton tuple to be
714
715
// isomorphic to its element type. ???
715
- return MetadataResponse::forComplete (
716
- getElementMetadata (type.getElementType (0 ), eltRequest));
716
+ return getMetadataRecursive (type.getElementType (0 ), request);
717
717
718
718
case 2 : {
719
- auto elt0Metadata = getElementMetadata (type.getElementType (0 ), eltRequest );
720
- auto elt1Metadata = getElementMetadata (type.getElementType (1 ), eltRequest );
719
+ auto elt0Metadata = getElementMetadata (type.getElementType (0 ));
720
+ auto elt1Metadata = getElementMetadata (type.getElementType (1 ));
721
721
722
722
llvm::Value *args[] = {
723
+ request.get (IGF),
723
724
elt0Metadata, elt1Metadata,
724
725
getTupleLabelsString (IGF.IGM , type, useLabels),
725
726
llvm::ConstantPointerNull::get (IGF.IGM .WitnessTablePtrTy ) // proposed
726
727
};
727
728
728
729
auto call = IGF.Builder .CreateCall (IGF.IGM .getGetTupleMetadata2Fn (),
729
730
args);
731
+ call->setCallingConv (IGF.IGM .SwiftCC );
730
732
call->setDoesNotThrow ();
731
733
732
- return MetadataResponse::forComplete ( call);
734
+ return MetadataResponse::handle (IGF, request, call);
733
735
}
734
736
735
737
case 3 : {
736
- auto elt0Metadata = getElementMetadata (type.getElementType (0 ), eltRequest );
737
- auto elt1Metadata = getElementMetadata (type.getElementType (1 ), eltRequest );
738
- auto elt2Metadata = getElementMetadata (type.getElementType (2 ), eltRequest );
738
+ auto elt0Metadata = getElementMetadata (type.getElementType (0 ));
739
+ auto elt1Metadata = getElementMetadata (type.getElementType (1 ));
740
+ auto elt2Metadata = getElementMetadata (type.getElementType (2 ));
739
741
740
742
llvm::Value *args[] = {
743
+ request.get (IGF),
741
744
elt0Metadata, elt1Metadata, elt2Metadata,
742
745
getTupleLabelsString (IGF.IGM , type, useLabels),
743
746
llvm::ConstantPointerNull::get (IGF.IGM .WitnessTablePtrTy ) // proposed
744
747
};
745
748
746
749
auto call = IGF.Builder .CreateCall (IGF.IGM .getGetTupleMetadata3Fn (),
747
750
args);
751
+ call->setCallingConv (IGF.IGM .SwiftCC );
748
752
call->setDoesNotThrow ();
749
753
750
- return MetadataResponse::forComplete ( call);
754
+ return MetadataResponse::handle (IGF, request, call);
751
755
}
752
756
default :
753
757
// TODO: use a caching entrypoint (with all information
@@ -764,7 +768,7 @@ static MetadataResponse emitTupleTypeMetadataRef(IRGenFunction &IGF,
764
768
IGF.IGM .getPointerSize () * elements.size ());
765
769
for (auto i : indices (elements)) {
766
770
// Find the metadata pointer for this element.
767
- llvm::Value *eltMetadata = getElementMetadata (elements[i], eltRequest );
771
+ llvm::Value *eltMetadata = getElementMetadata (elements[i]);
768
772
769
773
// GEP to the appropriate element and store.
770
774
Address eltPtr = IGF.Builder .CreateStructGEP (buffer, i,
@@ -778,6 +782,7 @@ static MetadataResponse emitTupleTypeMetadataRef(IRGenFunction &IGF,
778
782
TupleTypeFlags flags =
779
783
TupleTypeFlags ().withNumElements (elements.size ());
780
784
llvm::Value *args[] = {
785
+ request.get (IGF),
781
786
llvm::ConstantInt::get (IGF.IGM .SizeTy , flags.getIntValue ()),
782
787
pointerToFirst,
783
788
getTupleLabelsString (IGF.IGM , type, useLabels),
@@ -786,12 +791,13 @@ static MetadataResponse emitTupleTypeMetadataRef(IRGenFunction &IGF,
786
791
787
792
auto call = IGF.Builder .CreateCall (IGF.IGM .getGetTupleMetadataFn (),
788
793
args);
794
+ call->setCallingConv (IGF.IGM .SwiftCC );
789
795
call->setDoesNotThrow ();
790
796
791
797
IGF.Builder .CreateLifetimeEnd (buffer,
792
798
IGF.IGM .getPointerSize () * elements.size ());
793
799
794
- return MetadataResponse::forComplete ( call);
800
+ return MetadataResponse::handle (IGF, request, call);
795
801
}
796
802
}
797
803
@@ -882,8 +888,7 @@ namespace {
882
888
auto response = emitTupleTypeMetadataRef (IGF, type, request,
883
889
/* labels*/ true ,
884
890
[&](CanType eltType, DynamicMetadataRequest eltRequest) {
885
- assert (eltRequest.canResponseStatusBeIgnored ());
886
- return IGF.emitTypeMetadataRef (eltType, eltRequest).getMetadata ();
891
+ return IGF.emitTypeMetadataRef (eltType, eltRequest);
887
892
});
888
893
889
894
return setLocal (type, response);
@@ -1651,24 +1656,23 @@ irgen::emitInPlaceTypeMetadataAccessFunctionBody(IRGenFunction &IGF,
1651
1656
// / construction of the metadata value just involves calling idempotent
1652
1657
// / metadata-construction functions. It is not used for the in-place
1653
1658
// / initialization of non-generic nominal type metadata.
1654
- static llvm::Value *
1659
+ static MetadataResponse
1655
1660
emitTypeMetadataAccessFunctionBody (IRGenFunction &IGF,
1661
+ DynamicMetadataRequest request,
1656
1662
CanType type) {
1657
1663
assert (!type->hasArchetype () &&
1658
1664
" cannot emit metadata accessor for context-dependent type" );
1659
1665
1660
1666
// We only take this path for non-generic nominal types.
1661
1667
auto typeDecl = type->getAnyNominal ();
1662
1668
if (!typeDecl)
1663
- return emitDirectTypeMetadataRef (IGF, type, MetadataState::Complete)
1664
- .getMetadata ();
1669
+ return emitDirectTypeMetadataRef (IGF, type, request);
1665
1670
1666
1671
if (typeDecl->isGenericContext () &&
1667
1672
!(isa<ClassDecl>(typeDecl) &&
1668
1673
isa<ClangModuleUnit>(typeDecl->getModuleScopeContext ()))) {
1669
1674
// This is a metadata accessor for a fully substituted generic type.
1670
- return emitDirectTypeMetadataRef (IGF, type, MetadataState::Complete)
1671
- .getMetadata ();
1675
+ return emitDirectTypeMetadataRef (IGF, type, request);
1672
1676
}
1673
1677
1674
1678
// We should never be emitting a metadata accessor for resilient nominal
@@ -1687,18 +1691,19 @@ emitTypeMetadataAccessFunctionBody(IRGenFunction &IGF,
1687
1691
if (auto classDecl = dyn_cast<ClassDecl>(typeDecl)) {
1688
1692
// We emit a completely different pattern for foreign classes.
1689
1693
if (classDecl->getForeignClassKind () == ClassDecl::ForeignKind::CFType) {
1690
- return emitForeignTypeMetadataRef (IGF, type);
1694
+ return MetadataResponse::forComplete (
1695
+ emitForeignTypeMetadataRef (IGF, type));
1691
1696
}
1692
1697
1693
1698
// Classes that might not have Swift metadata use a different
1694
1699
// symbol name.
1695
1700
if (!hasKnownSwiftMetadata (IGF.IGM , classDecl)) {
1696
- return emitObjCMetadataRef (IGF, classDecl);
1701
+ return MetadataResponse::forComplete ( emitObjCMetadataRef (IGF, classDecl) );
1697
1702
}
1698
1703
1699
1704
// Imported value types require foreign metadata uniquing.
1700
1705
} else if (isa<ClangModuleUnit>(typeDecl->getModuleScopeContext ())) {
1701
- return emitForeignTypeMetadataRef (IGF, type);
1706
+ return MetadataResponse::forComplete ( emitForeignTypeMetadataRef (IGF, type) );
1702
1707
}
1703
1708
1704
1709
// Okay, everything else is built from a Swift metadata object.
@@ -1707,7 +1712,7 @@ emitTypeMetadataAccessFunctionBody(IRGenFunction &IGF,
1707
1712
// We should not be doing more serious work along this path.
1708
1713
assert (isTypeMetadataAccessTrivial (IGF.IGM , type));
1709
1714
1710
- return metadata;
1715
+ return MetadataResponse::forComplete ( metadata) ;
1711
1716
}
1712
1717
1713
1718
// / Get or create an accessor function to the given non-dependent type.
@@ -1762,10 +1767,7 @@ llvm::Function *irgen::getTypeMetadataAccessFunction(IRGenModule &IGM,
1762
1767
llvm::Constant *cacheVariable) {
1763
1768
// We should not be called with ForDefinition for nominal types
1764
1769
// that require in-place initialization.
1765
- // We should also not be called for types that require more interesting
1766
- // initialization that really requires the request/response machinery.
1767
- return MetadataResponse::forComplete (
1768
- emitTypeMetadataAccessFunctionBody (IGF, type));
1770
+ return emitTypeMetadataAccessFunctionBody (IGF, request, type);
1769
1771
});
1770
1772
}
1771
1773
@@ -1959,8 +1961,10 @@ namespace {
1959
1961
auto response = emitTupleTypeMetadataRef (IGF, type, request,
1960
1962
/* labels*/ false ,
1961
1963
[&](CanType eltType, DynamicMetadataRequest eltRequest) {
1962
- assert (eltRequest.canResponseStatusBeIgnored ());
1963
- return visit (eltType, eltRequest);
1964
+ // This use of 'forComplete' is technically questionable, but in
1965
+ // this class we're always producing responses we can ignore, so
1966
+ // it's okay.
1967
+ return MetadataResponse::forComplete (visit (eltType, eltRequest));
1964
1968
});
1965
1969
1966
1970
return setLocal (type, response);
0 commit comments