@@ -2792,55 +2792,70 @@ void TypeRepr::dump() const {
2792
2792
llvm::errs () << ' \n ' ;
2793
2793
}
2794
2794
2795
- void ProtocolConformanceRef::dump () const {
2796
- dump (llvm::errs ());
2797
- }
2798
-
2799
- void ProtocolConformanceRef::dump (llvm::raw_ostream &out,
2800
- unsigned indent) const {
2801
- if (isConcrete ()) {
2802
- getConcrete ()->dump (out, indent);
2795
+ // Recursive helpers to avoid infinite recursion for recursive protocol
2796
+ // conformances.
2797
+ static void dumpProtocolConformanceRec (
2798
+ const ProtocolConformance *conformance, llvm::raw_ostream &out,
2799
+ unsigned indent,
2800
+ llvm::SmallPtrSetImpl<const ProtocolConformance *> &visited);
2801
+
2802
+ static void dumpProtocolConformanceRefRec (
2803
+ const ProtocolConformanceRef conformance, llvm::raw_ostream &out,
2804
+ unsigned indent,
2805
+ llvm::SmallPtrSetImpl<const ProtocolConformance *> &visited) {
2806
+ if (conformance.isConcrete ()) {
2807
+ dumpProtocolConformanceRec (conformance.getConcrete (), out, indent, visited);
2803
2808
} else {
2804
2809
out.indent (indent) << " (abstract_conformance protocol="
2805
- << getAbstract ()->getName ();
2810
+ << conformance. getAbstract ()->getName ();
2806
2811
PrintWithColorRAII (out, ParenthesisColor) << ' )' ;
2807
2812
out << ' \n ' ;
2808
2813
}
2809
2814
}
2810
2815
2811
- void ProtocolConformance::dump () const {
2812
- auto &out = llvm::errs ();
2813
- dump (out);
2814
- out << ' \n ' ;
2815
- }
2816
+ static void dumpProtocolConformanceRec (
2817
+ const ProtocolConformance *conformance, llvm::raw_ostream &out,
2818
+ unsigned indent,
2819
+ llvm::SmallPtrSetImpl<const ProtocolConformance *> &visited) {
2820
+ // A recursive conformance shouldn't have its contents printed, or there's
2821
+ // infinite recursion. (This also avoids printing things that occur multiple
2822
+ // times in a conformance hierarchy.)
2823
+ auto shouldPrintDetails = visited.insert (conformance).second ;
2816
2824
2817
- void ProtocolConformance::dump (llvm::raw_ostream &out, unsigned indent) const {
2818
2825
auto printCommon = [&](StringRef kind) {
2819
2826
out.indent (indent);
2820
2827
PrintWithColorRAII (out, ParenthesisColor) << ' (' ;
2821
- out << kind << " _conformance type=" << getType ()
2822
- << " protocol=" << getProtocol ()->getName ();
2828
+ out << kind << " _conformance type=" << conformance->getType ()
2829
+ << " protocol=" << conformance->getProtocol ()->getName ();
2830
+
2831
+ if (!shouldPrintDetails)
2832
+ out << " (details printed above)" ;
2823
2833
};
2824
2834
2825
- switch (getKind ()) {
2835
+ switch (conformance-> getKind ()) {
2826
2836
case ProtocolConformanceKind::Normal: {
2827
- auto normal = cast<NormalProtocolConformance>(this );
2837
+ auto normal = cast<NormalProtocolConformance>(conformance );
2828
2838
2829
2839
printCommon (" normal" );
2840
+ if (!shouldPrintDetails)
2841
+ break ;
2842
+
2830
2843
// Maybe print information about the conforming context?
2831
2844
if (normal->isLazilyLoaded ()) {
2832
2845
out << " lazy" ;
2833
2846
} else {
2834
- forEachTypeWitness (nullptr , [&](const AssociatedTypeDecl *req,
2835
- Type ty, const TypeDecl *) -> bool {
2836
- out << ' \n ' ;
2837
- out.indent (indent + 2 );
2838
- PrintWithColorRAII (out, ParenthesisColor) << ' (' ;
2839
- out << " assoc_type req=" << req->getName () << " type=" ;
2840
- PrintWithColorRAII (out, TypeColor) << ty;
2841
- PrintWithColorRAII (out, ParenthesisColor) << ' )' ;
2842
- return false ;
2843
- });
2847
+ normal->forEachTypeWitness (
2848
+ nullptr ,
2849
+ [&](const AssociatedTypeDecl *req, Type ty,
2850
+ const TypeDecl *) -> bool {
2851
+ out << ' \n ' ;
2852
+ out.indent (indent + 2 );
2853
+ PrintWithColorRAII (out, ParenthesisColor) << ' (' ;
2854
+ out << " assoc_type req=" << req->getName () << " type=" ;
2855
+ PrintWithColorRAII (out, TypeColor) << ty;
2856
+ PrintWithColorRAII (out, ParenthesisColor) << ' )' ;
2857
+ return false ;
2858
+ });
2844
2859
normal->forEachValueWitness (nullptr , [&](const ValueDecl *req,
2845
2860
Witness witness) {
2846
2861
out << ' \n ' ;
@@ -2857,9 +2872,9 @@ void ProtocolConformance::dump(llvm::raw_ostream &out, unsigned indent) const {
2857
2872
PrintWithColorRAII (out, ParenthesisColor) << ' )' ;
2858
2873
});
2859
2874
2860
- for (auto conformance : normal->getSignatureConformances ()) {
2875
+ for (auto sigConf : normal->getSignatureConformances ()) {
2861
2876
out << ' \n ' ;
2862
- conformance. dump ( out, indent + 2 );
2877
+ dumpProtocolConformanceRefRec (sigConf, out, indent + 2 , visited );
2863
2878
}
2864
2879
}
2865
2880
@@ -2872,31 +2887,57 @@ void ProtocolConformance::dump(llvm::raw_ostream &out, unsigned indent) const {
2872
2887
}
2873
2888
2874
2889
case ProtocolConformanceKind::Inherited: {
2875
- auto conf = cast<InheritedProtocolConformance>(this );
2890
+ auto conf = cast<InheritedProtocolConformance>(conformance );
2876
2891
printCommon (" inherited" );
2892
+ if (!shouldPrintDetails)
2893
+ break ;
2894
+
2877
2895
out << ' \n ' ;
2878
- conf->getInheritedConformance ()->dump (out, indent + 2 );
2896
+ dumpProtocolConformanceRec (conf->getInheritedConformance (), out, indent + 2 ,
2897
+ visited);
2879
2898
break ;
2880
2899
}
2881
2900
2882
2901
case ProtocolConformanceKind::Specialized: {
2883
- auto conf = cast<SpecializedProtocolConformance>(this );
2902
+ auto conf = cast<SpecializedProtocolConformance>(conformance );
2884
2903
printCommon (" specialized" );
2904
+ if (!shouldPrintDetails)
2905
+ break ;
2906
+
2885
2907
out << ' \n ' ;
2886
2908
conf->getSubstitutionMap ().dump (out);
2887
2909
for (auto subReq : conf->getConditionalRequirements ()) {
2888
2910
out.indent (indent + 2 );
2889
2911
subReq.dump (out);
2890
2912
out << ' \n ' ;
2891
2913
}
2892
- conf->getGenericConformance ()->dump (out, indent + 2 );
2914
+ dumpProtocolConformanceRec (conf->getGenericConformance (), out, indent + 2 ,
2915
+ visited);
2893
2916
break ;
2894
2917
}
2895
2918
}
2896
2919
2897
2920
PrintWithColorRAII (out, ParenthesisColor) << ' )' ;
2898
2921
}
2899
2922
2923
+ void ProtocolConformanceRef::dump () const { dump (llvm::errs ()); }
2924
+
2925
+ void ProtocolConformanceRef::dump (llvm::raw_ostream &out,
2926
+ unsigned indent) const {
2927
+ llvm::SmallPtrSet<const ProtocolConformance *, 8 > visited;
2928
+ dumpProtocolConformanceRefRec (*this , out, indent, visited);
2929
+ }
2930
+ void ProtocolConformance::dump () const {
2931
+ auto &out = llvm::errs ();
2932
+ dump (out);
2933
+ out << ' \n ' ;
2934
+ }
2935
+
2936
+ void ProtocolConformance::dump (llvm::raw_ostream &out, unsigned indent) const {
2937
+ llvm::SmallPtrSet<const ProtocolConformance *, 8 > visited;
2938
+ dumpProtocolConformanceRec (this , out, indent, visited);
2939
+ }
2940
+
2900
2941
// ===----------------------------------------------------------------------===//
2901
2942
// Dumping for Types.
2902
2943
// ===----------------------------------------------------------------------===//
0 commit comments