Skip to content

Commit 12d9cc2

Browse files
committed
Reflection: Add a DEBUG_TYPE_LOWERING #ifdef for diagnosing problems
To avoid crashing tools, we just propagate failure instead of asserting. This makes debugging more difficult, though. When this macro is enabled, messages are printed to standard error to pinpoint the exact reason that type lowering bailed out.
1 parent 95bc009 commit 12d9cc2

File tree

1 file changed

+43
-11
lines changed

1 file changed

+43
-11
lines changed

stdlib/public/Reflection/TypeLowering.cpp

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424

2525
#include <iostream>
2626

27+
#ifdef DEBUG_TYPE_LOWERING
28+
#define DEBUG(expr) expr;
29+
#else
30+
#define DEBUG(expr)
31+
#endif
32+
2733
[[noreturn]]
2834
static void unreachable(const char *Message) {
2935
std::cerr << "fatal error: " << Message << "\n";
@@ -239,6 +245,7 @@ class ExistentialTypeInfoBuilder {
239245

240246
const FieldDescriptor *FD = TC.getBuilder().getFieldTypeInfo(P);
241247
if (FD == nullptr) {
248+
DEBUG(std::cerr << "No field descriptor: "; P->dump())
242249
Invalid = true;
243250
continue;
244251
}
@@ -275,6 +282,7 @@ class ExistentialTypeInfoBuilder {
275282
if (auto *P = dyn_cast<const ProtocolTypeRef>(TR)) {
276283
Protocols.push_back(P);
277284
} else {
285+
DEBUG(std::cerr << "Not a protocol: "; TR->dump())
278286
Invalid = true;
279287
}
280288
}
@@ -286,8 +294,10 @@ class ExistentialTypeInfoBuilder {
286294
return nullptr;
287295

288296
if (ObjC) {
289-
if (WitnessTableCount > 0)
297+
if (WitnessTableCount > 0) {
298+
DEBUG(std::cerr << "@objc existential with witness tables\n");
290299
return nullptr;
300+
}
291301

292302
return TC.getReferenceTypeInfo(ReferenceKind::Strong,
293303
ReferenceCounting::Unknown);
@@ -316,8 +326,10 @@ class ExistentialTypeInfoBuilder {
316326
break;
317327
case ExistentialTypeRepresentation::Opaque: {
318328
auto *TI = TC.getTypeInfo(TC.getRawPointerTypeRef());
319-
if (TI == nullptr)
329+
if (TI == nullptr) {
330+
DEBUG(std::cerr << "No TypeInfo for RawPointer\n");
320331
return nullptr;
332+
}
321333

322334
// Non-class existentials consist of a three-word buffer,
323335
// value metadata, and finally zero or more witness tables.
@@ -345,8 +357,10 @@ class ExistentialTypeInfoBuilder {
345357
return nullptr;
346358

347359
if (ObjC) {
348-
if (WitnessTableCount > 0)
360+
if (WitnessTableCount > 0) {
361+
DEBUG(std::cerr << "@objc existential with witness tables\n");
349362
return nullptr;
363+
}
350364

351365
return TC.getAnyMetatypeTypeInfo();
352366
}
@@ -390,6 +404,7 @@ void RecordTypeInfoBuilder::addField(const std::string &Name,
390404
const TypeRef *TR) {
391405
const TypeInfo *TI = TC.getTypeInfo(TR);
392406
if (TI == nullptr) {
407+
DEBUG(std::cerr << "No TypeInfo for field type: "; TR->dump());
393408
Invalid = true;
394409
return;
395410
}
@@ -436,8 +451,10 @@ TypeConverter::getReferenceTypeInfo(ReferenceKind Kind,
436451
// Weak references do not have any extra inhabitants.
437452

438453
auto *BuiltinTI = Builder.getBuiltinTypeInfo(TR);
439-
if (BuiltinTI == nullptr)
454+
if (BuiltinTI == nullptr) {
455+
DEBUG(std::cerr << "No TypeInfo for reference type: "; TR->dump());
440456
return nullptr;
457+
}
441458

442459
unsigned numExtraInhabitants = BuiltinTI->NumExtraInhabitants;
443460
if (Kind == ReferenceKind::Weak)
@@ -461,8 +478,10 @@ TypeConverter::getThinFunctionTypeInfo() {
461478

462479
auto *descriptor = getBuilder().getBuiltinTypeInfo(
463480
getThinFunctionTypeRef());
464-
if (descriptor == nullptr)
481+
if (descriptor == nullptr) {
482+
DEBUG(std::cerr << "No TypeInfo for function type\n");
465483
return nullptr;
484+
}
466485

467486
ThinFunctionTI = makeTypeInfo<BuiltinTypeInfo>(descriptor);
468487

@@ -495,8 +514,10 @@ TypeConverter::getAnyMetatypeTypeInfo() {
495514

496515
auto *descriptor = getBuilder().getBuiltinTypeInfo(
497516
getAnyMetatypeTypeRef());
498-
if (descriptor == nullptr)
517+
if (descriptor == nullptr) {
518+
DEBUG(std::cerr << "No TypeInfo for metatype type\n");
499519
return nullptr;
520+
}
500521

501522
AnyMetatypeTI = makeTypeInfo<BuiltinTypeInfo>(descriptor);
502523

@@ -837,6 +858,7 @@ class EnumTypeInfoBuilder {
837858
void addCase(const std::string &Name, const TypeRef *TR,
838859
const TypeInfo *TI) {
839860
if (TI == nullptr) {
861+
DEBUG(std::cerr << "No TypeInfo for case type: "; TR->dump());
840862
Invalid = true;
841863
return;
842864
}
@@ -967,8 +989,10 @@ class LowerType
967989
/// Otherwise, get the fixed layout information from reflection
968990
/// metadata.
969991
auto *descriptor = TC.getBuilder().getBuiltinTypeInfo(B);
970-
if (descriptor == nullptr)
992+
if (descriptor == nullptr) {
993+
DEBUG(std::cerr << "No TypeInfo for builtin type: "; B->dump());
971994
return nullptr;
995+
}
972996
return TC.makeTypeInfo<BuiltinTypeInfo>(descriptor);
973997
}
974998

@@ -982,6 +1006,7 @@ class LowerType
9821006
return TC.makeTypeInfo<BuiltinTypeInfo>(ImportedTypeDescriptor);
9831007

9841008
// Otherwise, we're out of luck.
1009+
DEBUG(std::cerr << "No TypeInfo for nominal type: "; TR->dump());
9851010
return nullptr;
9861011
}
9871012

@@ -1009,7 +1034,7 @@ class LowerType
10091034
case FieldDescriptorKind::ObjCProtocol:
10101035
case FieldDescriptorKind::ClassProtocol:
10111036
case FieldDescriptorKind::Protocol:
1012-
// Invalid field descriptor
1037+
DEBUG(std::cerr << "Invalid field descriptor: "; TR->dump());
10131038
return nullptr;
10141039
}
10151040
}
@@ -1060,6 +1085,7 @@ class LowerType
10601085
const TypeInfo *visitMetatypeTypeRef(const MetatypeTypeRef *M) {
10611086
switch (HasSingletonMetatype().visit(M)) {
10621087
case MetatypeRepresentation::Unknown:
1088+
DEBUG(std::cerr << "Unknown metatype representation: "; M->dump());
10631089
return nullptr;
10641090
case MetatypeRepresentation::Thin:
10651091
return TC.getEmptyTypeInfo();
@@ -1079,7 +1105,7 @@ class LowerType
10791105
for (auto *P : PC->getProtocols())
10801106
builder.addProtocol(P);
10811107
} else {
1082-
// Invalid TypeRef
1108+
DEBUG(std::cerr << "Invalid existential metatype: "; EM->dump());
10831109
return nullptr;
10841110
}
10851111

@@ -1114,8 +1140,10 @@ class LowerType
11141140
const TypeInfo *
11151141
rebuildStorageTypeInfo(const TypeInfo *TI, ReferenceKind Kind) {
11161142
// If we can't lower the original storage type, give up.
1117-
if (TI == nullptr)
1143+
if (TI == nullptr) {
1144+
DEBUG(std::cerr << "Invalid reference type");
11181145
return nullptr;
1146+
}
11191147

11201148
// Simple case: Just change the reference kind
11211149
if (auto *ReferenceTI = dyn_cast<ReferenceTypeInfo>(TI))
@@ -1156,6 +1184,7 @@ class LowerType
11561184
}
11571185

11581186
// Anything else -- give up
1187+
DEBUG(std::cerr << "Invalid reference type");
11591188
return nullptr;
11601189
}
11611190

@@ -1213,8 +1242,10 @@ const TypeInfo *TypeConverter::getClassInstanceTypeInfo(const TypeRef *TR,
12131242
unsigned start,
12141243
unsigned align) {
12151244
const FieldDescriptor *FD = getBuilder().getFieldTypeInfo(TR);
1216-
if (FD == nullptr)
1245+
if (FD == nullptr) {
1246+
DEBUG(std::cerr << "No field descriptor: "; TR->dump());
12171247
return nullptr;
1248+
}
12181249

12191250
switch (FD->Kind) {
12201251
case FieldDescriptorKind::Class:
@@ -1238,6 +1269,7 @@ const TypeInfo *TypeConverter::getClassInstanceTypeInfo(const TypeRef *TR,
12381269
case FieldDescriptorKind::ClassProtocol:
12391270
case FieldDescriptorKind::Protocol:
12401271
// Invalid field descriptor.
1272+
DEBUG(std::cerr << "Invalid field descriptor: "; TR->dump());
12411273
return nullptr;
12421274
}
12431275
}

0 commit comments

Comments
 (0)