26
26
#include " swift/AST/Initializer.h"
27
27
#include " swift/AST/MacroDefinition.h"
28
28
#include " swift/AST/NameLookupRequests.h"
29
+ #include " swift/AST/PackConformance.h"
29
30
#include " swift/AST/ParameterList.h"
30
31
#include " swift/AST/Pattern.h"
31
32
#include " swift/AST/PrettyStackTrace.h"
@@ -498,6 +499,9 @@ class ProtocolConformanceDeserializer {
498
499
ModuleFile::Serialized<ProtocolConformance *> &entry);
499
500
Expected<ProtocolConformance *>
500
501
readNormalProtocolConformanceXRef (ArrayRef<uint64_t > data);
502
+
503
+ Expected<PackConformance *>
504
+ read (ModuleFile::Serialized<PackConformance *> &entry);
501
505
};
502
506
} // end namespace swift
503
507
@@ -761,6 +765,65 @@ ProtocolConformanceDeserializer::readNormalProtocolConformance(
761
765
return conformance;
762
766
}
763
767
768
+ Expected<PackConformance*>
769
+ ProtocolConformanceDeserializer::read (
770
+ ModuleFile::Serialized<PackConformance *> &conformanceEntry) {
771
+ using namespace decls_block ;
772
+
773
+ SmallVector<uint64_t , 16 > scratch;
774
+
775
+ llvm::BitstreamEntry entry =
776
+ MF.fatalIfUnexpected (MF.DeclTypeCursor .advance ());
777
+
778
+ if (entry.Kind != llvm::BitstreamEntry::Record) {
779
+ // We don't know how to serialize types represented by sub-blocks.
780
+ return MF.diagnoseFatal ();
781
+ }
782
+
783
+ StringRef blobData;
784
+ unsigned kind = MF.fatalIfUnexpected (
785
+ MF.DeclTypeCursor .readRecord (entry.ID , scratch, &blobData));
786
+ assert (blobData.empty ());
787
+
788
+ if (kind != decls_block::PACK_CONFORMANCE)
789
+ return MF.diagnoseFatal (llvm::make_error<InvalidRecordKindError>(kind));
790
+
791
+ TypeID patternTypeID;
792
+ DeclID protocolID;
793
+ ArrayRef<uint64_t > patternConformanceIDs;
794
+ PackConformanceLayout::readRecord (scratch,
795
+ patternTypeID, protocolID,
796
+ patternConformanceIDs);
797
+
798
+ auto patternTypeOrError = MF.getTypeChecked (patternTypeID);
799
+ if (!patternTypeOrError)
800
+ return patternTypeOrError.takeError ();
801
+ auto patternType = patternTypeOrError.get ();
802
+
803
+ auto protocolOrError = MF.getDeclChecked (protocolID);
804
+ if (!protocolOrError)
805
+ return protocolOrError.takeError ();
806
+ auto *protocol = protocolOrError.get ();
807
+
808
+ PrettyStackTraceType trace (MF.getAssociatedModule ()->getASTContext (),
809
+ " reading pack conformance for" ,
810
+ patternType);
811
+
812
+ SmallVector<ProtocolConformanceRef, 4 > patternConformances;
813
+ for (auto confID : patternConformanceIDs) {
814
+ auto confOrError = MF.getConformanceChecked (confID);
815
+ if (!confOrError)
816
+ return confOrError.takeError ();
817
+ patternConformances.push_back (confOrError.get ());
818
+ }
819
+
820
+ auto conformance =
821
+ PackConformance::get (patternType->castTo <PackType>(),
822
+ cast<ProtocolDecl>(protocol),
823
+ patternConformances);
824
+ return conformance;
825
+ }
826
+
764
827
ProtocolConformanceRef
765
828
ModuleFile::getConformance (ProtocolConformanceID id,
766
829
GenericEnvironment *genericEnv) {
@@ -777,42 +840,68 @@ ModuleFile::getConformanceChecked(ProtocolConformanceID conformanceID,
777
840
778
841
if (conformanceID == 0 ) return ProtocolConformanceRef::forInvalid ();
779
842
780
- // If the low bit is sit, this is an abstract conformance.
781
- if ((conformanceID & 1 ) == 0 ) {
782
- auto protocolID = conformanceID >> 1 ;
843
+ switch (conformanceID & SerializedProtocolConformanceKind::Mask) {
844
+ case SerializedProtocolConformanceKind::Abstract: {
845
+ auto protocolID = conformanceID >> SerializedProtocolConformanceKind::Shift ;
783
846
auto maybeProtocol = getDeclChecked (protocolID);
784
847
if (!maybeProtocol)
785
848
return maybeProtocol.takeError ();
786
849
auto proto = cast<ProtocolDecl>(maybeProtocol.get ());
787
850
return ProtocolConformanceRef (proto);
788
851
}
789
852
790
- // Otherwise, it's a concrete conformance.
791
- auto conformanceIndex = (conformanceID >> 1 ) - 1 ;
792
- assert (conformanceIndex < Conformances.size () && " invalid conformance ID" );
793
- auto &conformanceOrOffset = Conformances[conformanceIndex];
794
- if (!conformanceOrOffset.isComplete ()) {
795
- BCOffsetRAII restoreOffset (DeclTypeCursor);
796
- if (auto error = diagnoseFatalIfNotSuccess (
797
- DeclTypeCursor.JumpToBit (conformanceOrOffset)))
798
- return std::move (error);
799
-
800
- auto result =
801
- ProtocolConformanceDeserializer (*this ).read (conformanceOrOffset);
802
- if (!result)
803
- return result.takeError ();
804
-
805
- conformanceOrOffset = result.get ();
806
- }
807
- auto conformance = conformanceOrOffset.get ();
808
- if (!genericEnv || !conformance->getType ()->hasTypeParameter ())
853
+ case SerializedProtocolConformanceKind::Concrete: {
854
+ auto conformanceIndex = (conformanceID >> SerializedProtocolConformanceKind::Shift) - 1 ;
855
+ assert (conformanceIndex < Conformances.size () && " invalid conformance ID" );
856
+ auto &conformanceOrOffset = Conformances[conformanceIndex];
857
+ if (!conformanceOrOffset.isComplete ()) {
858
+ BCOffsetRAII restoreOffset (DeclTypeCursor);
859
+ if (auto error = diagnoseFatalIfNotSuccess (
860
+ DeclTypeCursor.JumpToBit (conformanceOrOffset)))
861
+ return std::move (error);
862
+
863
+ auto result =
864
+ ProtocolConformanceDeserializer (*this ).read (conformanceOrOffset);
865
+ if (!result)
866
+ return result.takeError ();
867
+
868
+ conformanceOrOffset = result.get ();
869
+ }
870
+ auto conformance = conformanceOrOffset.get ();
871
+ if (!genericEnv || !conformance->getType ()->hasTypeParameter ())
872
+ return ProtocolConformanceRef (conformance);
873
+
874
+ // If we have a generic environment, map the conformance into context.
875
+ auto mappedConformance =
876
+ genericEnv->mapConformanceRefIntoContext (conformance->getType (),
877
+ ProtocolConformanceRef (conformance));
878
+ return mappedConformance.second ;
879
+ }
880
+
881
+ case SerializedProtocolConformanceKind::Pack: {
882
+ auto conformanceIndex = (conformanceID >> SerializedProtocolConformanceKind::Shift) - 1 ;
883
+ assert (conformanceIndex < Conformances.size () && " invalid pack conformance ID" );
884
+ auto &conformanceOrOffset = Conformances[conformanceIndex];
885
+ if (!conformanceOrOffset.isComplete ()) {
886
+ BCOffsetRAII restoreOffset (DeclTypeCursor);
887
+ if (auto error = diagnoseFatalIfNotSuccess (
888
+ DeclTypeCursor.JumpToBit (conformanceOrOffset)))
889
+ return std::move (error);
890
+
891
+ auto result =
892
+ ProtocolConformanceDeserializer (*this ).read (conformanceOrOffset);
893
+ if (!result)
894
+ return result.takeError ();
895
+
896
+ conformanceOrOffset = result.get ();
897
+ }
898
+ auto conformance = conformanceOrOffset.get ();
809
899
return ProtocolConformanceRef (conformance);
900
+ }
810
901
811
- // If we have a generic environment, map the conformance into context.
812
- auto mappedConformance =
813
- genericEnv->mapConformanceRefIntoContext (conformance->getType (),
814
- ProtocolConformanceRef (conformance));
815
- return mappedConformance.second ;
902
+ default :
903
+ llvm_unreachable (" Invalid conformance" );
904
+ }
816
905
}
817
906
818
907
GenericParamList *ModuleFile::maybeReadGenericParams (DeclContext *DC) {
0 commit comments