@@ -239,9 +239,14 @@ struct FieldTypeInfo {
239
239
240
240
// / Info about a protocol conformance read out from an Image
241
241
struct 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;
245
250
};
246
251
247
252
// / An implementation of MetadataReader's BuilderType concept for
@@ -1171,7 +1176,9 @@ class TypeRefBuilder {
1171
1176
public:
1172
1177
template <template <typename Runtime> class ObjCInteropKind ,
1173
1178
unsigned PointerSize>
1174
- void dumpConformanceSection (std::ostream &stream) {
1179
+ ConformanceCollectionResult collectAllConformances () {
1180
+ ConformanceCollectionResult result;
1181
+
1175
1182
// The Fields section has gathered info on types that includes their mangled
1176
1183
// names. Use that to build a dictionary from a type's demangled name to its
1177
1184
// mangeled name
@@ -1203,25 +1210,34 @@ class TypeRefBuilder {
1203
1210
auto optionalConformanceInfo =
1204
1211
conformanceReader.readConformanceDescriptor (conformanceAddr,
1205
1212
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 ());
1222
1217
}
1223
1218
}
1219
+ return result;
1220
+ }
1224
1221
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
+ }
1225
1241
for (auto &pair : typeConformances) {
1226
1242
stream << pair.first << " : " ;
1227
1243
bool first = true ;
@@ -1234,6 +1250,12 @@ class TypeRefBuilder {
1234
1250
}
1235
1251
stream << " \n " ;
1236
1252
}
1253
+
1254
+ // Report encountered errors
1255
+ for (auto &error : conformanceCollectionResult.Errors ) {
1256
+ stream << " Error reading conformance descriptor: "
1257
+ << error << " \n " ;
1258
+ }
1237
1259
}
1238
1260
1239
1261
template <template <typename Runtime> class ObjCInteropKind ,
0 commit comments