@@ -800,150 +800,6 @@ namespace {
800
800
801
801
ArrayRef<WitnessTableEntry> getEntries () const { return Entries; }
802
802
};
803
-
804
- // / A path through a protocol hierarchy.
805
- class ProtocolPath {
806
- IRGenModule &IGM;
807
-
808
- // / The destination protocol.
809
- ProtocolDecl *Dest;
810
-
811
- // / The path from the selected origin down to the destination
812
- // / protocol.
813
- SmallVector<WitnessIndex, 8 > ReversePath;
814
-
815
- // / The origin index to use.
816
- unsigned OriginIndex;
817
-
818
- // / The best path length we found.
819
- unsigned BestPathLength;
820
-
821
- public:
822
- // / Find a path from the given set of origins to the destination
823
- // / protocol.
824
- // /
825
- // / T needs to provide a couple of member functions:
826
- // / ProtocolDecl *getProtocol() const;
827
- // / const ProtocolInfo &getInfo() const;
828
- template <class T >
829
- ProtocolPath (IRGenModule &IGM, ArrayRef<T> origins, ProtocolDecl *dest)
830
- : IGM(IGM), Dest(dest), BestPathLength(~0U ) {
831
-
832
- // Consider each of the origins in turn, breaking out if any of
833
- // them yields a zero-length path.
834
- for (unsigned i = 0 , e = origins.size (); i != e; ++i) {
835
- auto &origin = origins[i];
836
- if (considerOrigin (origin.getProtocol (), origin.getInfo (), i))
837
- break ;
838
- }
839
-
840
- // Sanity check that we actually found a path at all.
841
- assert (BestPathLength != ~0U );
842
- assert (BestPathLength == ReversePath.size ());
843
- }
844
-
845
- // / Returns the index of the origin protocol we chose.
846
- unsigned getOriginIndex () const { return OriginIndex; }
847
-
848
- // / Apply the path to the given witness table.
849
- llvm::Value *apply (IRGenFunction &IGF, llvm::Value *wtable) const {
850
- for (unsigned i = ReversePath.size (); i != 0 ; --i) {
851
- wtable = emitInvariantLoadOfOpaqueWitness (IGF, wtable,
852
- ReversePath[i-1 ].forProtocolWitnessTable ());
853
- wtable = IGF.Builder .CreateBitCast (wtable, IGF.IGM .WitnessTablePtrTy );
854
- }
855
- return wtable;
856
- }
857
-
858
- private:
859
- // / Consider paths starting from a new origin protocol.
860
- // / Returns true if there's no point in considering other origins.
861
- bool considerOrigin (ProtocolDecl *origin, const ProtocolInfo &originInfo,
862
- unsigned originIndex) {
863
- assert (BestPathLength != 0 );
864
-
865
- // If the origin *is* the destination, we can stop here.
866
- if (origin == Dest) {
867
- OriginIndex = originIndex;
868
- BestPathLength = 0 ;
869
- ReversePath.clear ();
870
- return true ;
871
- }
872
-
873
- // Otherwise, if the origin gives rise to a better path, that's
874
- // also cool.
875
- if (findBetterPath (origin, originInfo, 0 )) {
876
- OriginIndex = originIndex;
877
- return BestPathLength == 0 ;
878
- }
879
-
880
- return false ;
881
- }
882
-
883
- // / Consider paths starting at the given protocol.
884
- bool findBetterPath (ProtocolDecl *proto, const ProtocolInfo &protoInfo,
885
- unsigned lengthSoFar) {
886
- assert (lengthSoFar < BestPathLength);
887
- assert (proto != Dest);
888
-
889
- // Keep track of whether we found a better path than the
890
- // previous best.
891
- bool foundBetter = false ;
892
- for (auto base : proto->getInheritedProtocols ()) {
893
- // ObjC protocols do not have witnesses.
894
- if (!Lowering::TypeConverter::protocolRequiresWitnessTable (base))
895
- continue ;
896
-
897
- auto baseIndex = protoInfo.getBaseIndex (base);
898
-
899
- // Compute the length down to this base.
900
- unsigned lengthToBase = lengthSoFar;
901
- if (!baseIndex.isPrefix ()) {
902
- lengthToBase++;
903
-
904
- // Don't consider this path if we reach a length that can't
905
- // possibly be better than the best so far.
906
- if (lengthToBase == BestPathLength) continue ;
907
- }
908
- assert (lengthToBase < BestPathLength);
909
-
910
- // If this base *is* the destination, go ahead and start
911
- // building the path into ReversePath.
912
- if (base == Dest) {
913
- // Reset the collected best-path information.
914
- BestPathLength = lengthToBase;
915
- ReversePath.clear ();
916
-
917
- // Otherwise, if there isn't a better path through this base,
918
- // don't accumulate anything in the path.
919
- } else {
920
- const ProtocolInfo &baseInfo =
921
- IGM.getProtocolInfo (base, ProtocolInfoKind::RequirementSignature);
922
- if (!findBetterPath (base, baseInfo, lengthToBase))
923
- continue ;
924
- }
925
-
926
- // Okay, we've found a better path, and ReversePath contains a
927
- // path leading from base to Dest.
928
- assert (BestPathLength >= lengthToBase);
929
- foundBetter = true ;
930
-
931
- // Add the link from proto to base if necessary.
932
- if (!baseIndex.isPrefix ()) {
933
- ReversePath.push_back (baseIndex);
934
-
935
- // If it isn't necessary, then we might be able to
936
- // short-circuit considering the bases of this protocol.
937
- } else {
938
- if (lengthSoFar == BestPathLength)
939
- return true ;
940
- }
941
- }
942
-
943
- return foundBetter;
944
- }
945
- };
946
-
947
803
} // end anonymous namespace
948
804
949
805
// / Return true if the witness table requires runtime instantiation to
@@ -2889,16 +2745,6 @@ void NecessaryBindings::addProtocolConformance(CanType type,
2889
2745
Requirements.insert ({type, conf.getAbstract ()});
2890
2746
}
2891
2747
2892
- llvm::Value *irgen::emitImpliedWitnessTableRef (IRGenFunction &IGF,
2893
- ArrayRef<ProtocolEntry> entries,
2894
- ProtocolDecl *target,
2895
- const GetWitnessTableFn &getWitnessTable) {
2896
- ProtocolPath path (IGF.IGM , entries, target);
2897
- auto wtable = getWitnessTable (path.getOriginIndex ());
2898
- wtable = path.apply (IGF, wtable);
2899
- return wtable;
2900
- }
2901
-
2902
2748
llvm::Value *irgen::emitWitnessTableRef (IRGenFunction &IGF,
2903
2749
CanType srcType,
2904
2750
ProtocolConformanceRef conformance) {
0 commit comments