@@ -1160,6 +1160,12 @@ class ExistentialTypeInfoBuilder {
1160
1160
unsigned WitnessTableCount;
1161
1161
bool Invalid;
1162
1162
1163
+ void markInvalid (const char *msg, const TypeRef *TR = nullptr ) {
1164
+ Invalid = true ;
1165
+ DEBUG_LOG (fprintf (stderr, " %s\n " , msg); if (TR) TR->dump ());
1166
+ TC.setError (msg, TR);
1167
+ }
1168
+
1163
1169
bool isSingleError () const {
1164
1170
// If we changed representation, it means we added a
1165
1171
// superclass constraint or an AnyObject member.
@@ -1191,8 +1197,7 @@ class ExistentialTypeInfoBuilder {
1191
1197
auto *NTD = dyn_cast<NominalTypeRef>(P);
1192
1198
auto *OP = dyn_cast<ObjCProtocolTypeRef>(P);
1193
1199
if (!NTD && !OP) {
1194
- DEBUG_LOG (fprintf (stderr, " Bad protocol: " ); P->dump ())
1195
- Invalid = true ;
1200
+ markInvalid (" bad protocol" , P);
1196
1201
continue ;
1197
1202
}
1198
1203
@@ -1204,8 +1209,7 @@ class ExistentialTypeInfoBuilder {
1204
1209
1205
1210
auto FD = TC.getBuilder ().getFieldDescriptor (P);
1206
1211
if (FD == nullptr ) {
1207
- DEBUG_LOG (fprintf (stderr, " No field descriptor: " ); P->dump ())
1208
- Invalid = true ;
1212
+ markInvalid (" no field descriptor" , P);
1209
1213
continue ;
1210
1214
}
1211
1215
@@ -1224,16 +1228,12 @@ class ExistentialTypeInfoBuilder {
1224
1228
// layering.
1225
1229
auto *SuperclassTI = TC.getTypeInfo (Superclass, nullptr );
1226
1230
if (SuperclassTI == nullptr ) {
1227
- DEBUG_LOG (fprintf (stderr, " No TypeInfo for superclass: " );
1228
- Superclass->dump ());
1229
- Invalid = true ;
1231
+ markInvalid (" no type info for superclass" , Superclass);
1230
1232
continue ;
1231
1233
}
1232
1234
1233
1235
if (!isa<ReferenceTypeInfo>(SuperclassTI)) {
1234
- DEBUG_LOG (fprintf (stderr, " Superclass not a reference type: " );
1235
- SuperclassTI->dump ());
1236
- Invalid = true ;
1236
+ markInvalid (" superclass not a reference type" , Superclass);
1237
1237
continue ;
1238
1238
}
1239
1239
@@ -1252,7 +1252,7 @@ class ExistentialTypeInfoBuilder {
1252
1252
case FieldDescriptorKind::Enum:
1253
1253
case FieldDescriptorKind::MultiPayloadEnum:
1254
1254
case FieldDescriptorKind::Class:
1255
- Invalid = true ;
1255
+ markInvalid ( " unexpected field descriptor kind " ) ;
1256
1256
continue ;
1257
1257
}
1258
1258
}
@@ -1283,8 +1283,7 @@ class ExistentialTypeInfoBuilder {
1283
1283
if (!isa<NominalTypeRef>(T) &&
1284
1284
!isa<BoundGenericTypeRef>(T) &&
1285
1285
!isa<ObjCClassTypeRef>(T)) {
1286
- DEBUG_LOG (fprintf (stderr, " Bad existential member: " ); T->dump ())
1287
- Invalid = true ;
1286
+ markInvalid (" bad existential member" , T);
1288
1287
return ;
1289
1288
}
1290
1289
@@ -1296,8 +1295,7 @@ class ExistentialTypeInfoBuilder {
1296
1295
1297
1296
const auto &FD = TC.getBuilder ().getFieldDescriptor (T);
1298
1297
if (FD == nullptr ) {
1299
- DEBUG_LOG (fprintf (stderr, " No field descriptor: " ); T->dump ())
1300
- Invalid = true ;
1298
+ markInvalid (" no field descriptor" , T);
1301
1299
return ;
1302
1300
}
1303
1301
@@ -1313,8 +1311,7 @@ class ExistentialTypeInfoBuilder {
1313
1311
break ;
1314
1312
1315
1313
default :
1316
- DEBUG_LOG (fprintf (stderr, " Bad existential member: " ); T->dump ())
1317
- Invalid = true ;
1314
+ markInvalid (" bad existential member" , T);
1318
1315
return ;
1319
1316
}
1320
1317
}
@@ -1324,10 +1321,6 @@ class ExistentialTypeInfoBuilder {
1324
1321
Representation = ExistentialTypeRepresentation::Class;
1325
1322
}
1326
1323
1327
- void markInvalid () {
1328
- Invalid = true ;
1329
- }
1330
-
1331
1324
const TypeInfo *build (remote::TypeInfoProvider *ExternalTypeInfo) {
1332
1325
examineProtocols ();
1333
1326
@@ -1407,7 +1400,7 @@ class ExistentialTypeInfoBuilder {
1407
1400
1408
1401
if (ObjC) {
1409
1402
if (WitnessTableCount > 0 ) {
1410
- DEBUG_LOG ( fprintf (stderr, " @objc existential with witness tables\n " ) );
1403
+ markInvalid ( " @objc existential with witness tables" );
1411
1404
return nullptr ;
1412
1405
}
1413
1406
@@ -1480,8 +1473,7 @@ void RecordTypeInfoBuilder::addField(
1480
1473
remote::TypeInfoProvider *ExternalTypeInfo) {
1481
1474
const TypeInfo *TI = TC.getTypeInfo (TR, ExternalTypeInfo);
1482
1475
if (TI == nullptr ) {
1483
- DEBUG_LOG (fprintf (stderr, " No TypeInfo for field type: " ); TR->dump ());
1484
- Invalid = true ;
1476
+ markInvalid (" no TypeInfo for field type" , TR);
1485
1477
return ;
1486
1478
}
1487
1479
@@ -1563,6 +1555,18 @@ const ReferenceTypeInfo *TypeConverter::getReferenceTypeInfo(
1563
1555
return TI;
1564
1556
}
1565
1557
1558
+ std::string TypeConverter::takeLastError () {
1559
+ if (!LastError.first )
1560
+ return {};
1561
+ std::stringstream s;
1562
+ s << " : " << LastError.first ;
1563
+ if (LastError.second )
1564
+ LastError.second ->dump (s);
1565
+
1566
+ LastError = {nullptr , nullptr };
1567
+ return s.str ();
1568
+ }
1569
+
1566
1570
// / Thin functions consist of a function pointer. We do not use
1567
1571
// / Builtin.RawPointer here, since the extra inhabitants differ.
1568
1572
const TypeInfo *
@@ -1996,6 +2000,12 @@ class EnumTypeInfoBuilder {
1996
2000
std::vector<FieldInfo> Cases;
1997
2001
bool Invalid;
1998
2002
2003
+ void markInvalid (const char *msg, const TypeRef *TR = nullptr ) {
2004
+ Invalid = true ;
2005
+ DEBUG_LOG (fprintf (stderr, " %s\n " , msg); if (TR) TR->dump ());
2006
+ TC.setError (msg, TR);
2007
+ }
2008
+
1999
2009
const TypeRef *getCaseTypeRef (FieldTypeInfo Case) {
2000
2010
// An indirect case is like a payload case with an argument type
2001
2011
// of Builtin.NativeObject.
@@ -2015,8 +2025,7 @@ class EnumTypeInfoBuilder {
2015
2025
void addCase (const std::string &Name, const TypeRef *TR,
2016
2026
const TypeInfo *TI) {
2017
2027
if (TI == nullptr ) {
2018
- DEBUG_LOG (fprintf (stderr, " No TypeInfo for case type: " ); TR->dump ());
2019
- Invalid = true ;
2028
+ markInvalid (" no type info for case type" , TR);
2020
2029
static TypeInfo emptyTI;
2021
2030
Cases.push_back ({Name, /* offset=*/ 0 , /* value=*/ -1 , TR, emptyTI});
2022
2031
} else {
@@ -2045,7 +2054,7 @@ class EnumTypeInfoBuilder {
2045
2054
2046
2055
std::vector<FieldTypeInfo> Fields;
2047
2056
if (!TC.getBuilder ().getFieldTypeRefs (TR, FD, ExternalTypeInfo, Fields)) {
2048
- Invalid = true ;
2057
+ markInvalid ( " cannot not get field types " , TR) ;
2049
2058
return nullptr ;
2050
2059
}
2051
2060
@@ -2060,7 +2069,7 @@ class EnumTypeInfoBuilder {
2060
2069
auto *CaseTI = TC.getTypeInfo (CaseTR, ExternalTypeInfo);
2061
2070
if (CaseTI == nullptr ) {
2062
2071
// We don't have typeinfo; something is very broken.
2063
- Invalid = true ;
2072
+ markInvalid ( " no type info for single enum case " , CaseTR) ;
2064
2073
return nullptr ;
2065
2074
} else if (Case.Indirect ) {
2066
2075
// An indirect case is non-empty (it stores a pointer)
@@ -2655,8 +2664,11 @@ TypeConverter::getTypeInfo(const TypeRef *TR,
2655
2664
ExternalTypeInfo ? ExternalTypeInfo->getId () : 0 ;
2656
2665
// See if we already computed the result
2657
2666
auto found = Cache.find ({TR, ExternalTypeInfoId});
2658
- if (found != Cache.end ())
2667
+ if (found != Cache.end ()) {
2668
+ if (!found->second && ErrorCache)
2669
+ LastError = ErrorCache->lookup ({TR, ExternalTypeInfoId});
2659
2670
return found->second ;
2671
+ }
2660
2672
2661
2673
// Detect invalid recursive value types (IRGen should not emit
2662
2674
// them in the first place, but there might be bugs)
@@ -2668,6 +2680,8 @@ TypeConverter::getTypeInfo(const TypeRef *TR,
2668
2680
// Compute the result and cache it
2669
2681
auto *TI = LowerType (*this , ExternalTypeInfo).visit (TR);
2670
2682
Cache.insert ({{TR, ExternalTypeInfoId}, TI});
2683
+ if (!TI && ErrorCache)
2684
+ ErrorCache->insert ({{TR, ExternalTypeInfoId}, LastError});
2671
2685
2672
2686
RecursionCheck.erase (TR);
2673
2687
0 commit comments