@@ -239,9 +239,14 @@ struct FieldTypeInfo {
239239
240240// / Info about a protocol conformance read out from an Image
241241struct ProtocolConformanceInfo {
242- std::string typeName;
243- std::string protocolName;
244- std::string mangledTypeName;
242+ std::string TypeName;
243+ std::string ProtocolName;
244+ std::string MangledTypeName;
245+ };
246+
247+ struct ConformanceCollectionResult {
248+ std::vector<ProtocolConformanceInfo> Conformances;
249+ std::vector<std::string> Errors;
245250};
246251
247252// / An implementation of MetadataReader's BuilderType concept for
@@ -1171,7 +1176,9 @@ class TypeRefBuilder {
11711176public:
11721177 template <template <typename Runtime> class ObjCInteropKind ,
11731178 unsigned PointerSize>
1174- void dumpConformanceSection (std::ostream &stream) {
1179+ ConformanceCollectionResult collectAllConformances () {
1180+ ConformanceCollectionResult result;
1181+
11751182 // The Fields section has gathered info on types that includes their mangled
11761183 // names. Use that to build a dictionary from a type's demangled name to its
11771184 // mangeled name
@@ -1203,25 +1210,34 @@ class TypeRefBuilder {
12031210 auto optionalConformanceInfo =
12041211 conformanceReader.readConformanceDescriptor (conformanceAddr,
12051212 typeNameToManglingMap);
1206- if (!optionalConformanceInfo.hasValue ()) {
1207- stream << " Error reading conformance descriptor: "
1208- << conformanceReader.Error << " \n " ;
1209- continue ;
1210- }
1211- auto conformanceInfo = optionalConformanceInfo.getValue ();
1212- auto typeConformancesKey = conformanceInfo.mangledTypeName + " (" +
1213- conformanceInfo.typeName + " )" ;
1214- if (typeConformances.count (typeConformancesKey) != 0 ) {
1215- typeConformances[typeConformancesKey].push_back (
1216- conformanceInfo.protocolName );
1217- } else {
1218- typeConformances.emplace (
1219- typeConformancesKey,
1220- std::vector<std::string>{conformanceInfo.protocolName });
1221- }
1213+ if (!optionalConformanceInfo.hasValue ())
1214+ result.Errors .push_back (conformanceReader.Error );
1215+ else
1216+ result.Conformances .push_back (optionalConformanceInfo.getValue ());
12221217 }
12231218 }
1219+ return result;
1220+ }
12241221
1222+ template <template <typename Runtime> class ObjCInteropKind ,
1223+ unsigned PointerSize>
1224+ void dumpConformanceSection (std::ostream &stream) {
1225+ auto conformanceCollectionResult = collectAllConformances<ObjCInteropKind, PointerSize>();
1226+
1227+ // Collect all conformances and aggregate them per-conforming-type.
1228+ std::unordered_map<std::string, std::vector<std::string>> typeConformances;
1229+ for (auto &conformanceInfo : conformanceCollectionResult.Conformances ) {
1230+ auto typeConformancesKey = conformanceInfo.MangledTypeName + " (" +
1231+ conformanceInfo.TypeName + " )" ;
1232+ if (typeConformances.count (typeConformancesKey) != 0 ) {
1233+ typeConformances[typeConformancesKey].push_back (
1234+ conformanceInfo.ProtocolName );
1235+ } else {
1236+ typeConformances.emplace (
1237+ typeConformancesKey,
1238+ std::vector<std::string>{conformanceInfo.ProtocolName });
1239+ }
1240+ }
12251241 for (auto &pair : typeConformances) {
12261242 stream << pair.first << " : " ;
12271243 bool first = true ;
@@ -1234,6 +1250,12 @@ class TypeRefBuilder {
12341250 }
12351251 stream << " \n " ;
12361252 }
1253+
1254+ // Report encountered errors
1255+ for (auto &error : conformanceCollectionResult.Errors ) {
1256+ stream << " Error reading conformance descriptor: "
1257+ << error << " \n " ;
1258+ }
12371259 }
12381260
12391261 template <template <typename Runtime> class ObjCInteropKind ,
0 commit comments