@@ -2062,32 +2062,37 @@ struct TargetTypeMetadataRecord {
2062
2062
union {
2063
2063
// / A direct reference to a nominal type descriptor.
2064
2064
RelativeDirectPointerIntPair<TargetTypeContextDescriptor<Runtime>,
2065
- TypeMetadataRecordKind >
2065
+ TypeReferenceKind >
2066
2066
DirectNominalTypeDescriptor;
2067
2067
2068
2068
// / An indirect reference to a nominal type descriptor.
2069
2069
RelativeDirectPointerIntPair<TargetTypeContextDescriptor<Runtime> * const ,
2070
- TypeMetadataRecordKind >
2070
+ TypeReferenceKind >
2071
2071
IndirectNominalTypeDescriptor;
2072
+
2073
+ // We only allow a subset of the TypeReferenceKinds here.
2074
+ // Should we just acknowledge that this is a different enum?
2072
2075
};
2073
2076
2074
2077
public:
2075
- TypeMetadataRecordKind getTypeKind () const {
2078
+ TypeReferenceKind getTypeKind () const {
2076
2079
return DirectNominalTypeDescriptor.getInt ();
2077
2080
}
2078
2081
2079
2082
const TargetTypeContextDescriptor<Runtime> *
2080
2083
getTypeContextDescriptor () const {
2081
2084
switch (getTypeKind ()) {
2082
- case TypeMetadataRecordKind ::DirectNominalTypeDescriptor:
2085
+ case TypeReferenceKind ::DirectNominalTypeDescriptor:
2083
2086
return DirectNominalTypeDescriptor.getPointer ();
2084
2087
2085
- case TypeMetadataRecordKind::Reserved:
2086
- case TypeMetadataRecordKind::IndirectObjCClass:
2087
- return nullptr ;
2088
-
2089
- case TypeMetadataRecordKind::IndirectNominalTypeDescriptor:
2088
+ case TypeReferenceKind::IndirectNominalTypeDescriptor:
2090
2089
return *IndirectNominalTypeDescriptor.getPointer ();
2090
+
2091
+ // These types (and any others we might add to TypeReferenceKind
2092
+ // in the future) are just never used in these lists.
2093
+ case TypeReferenceKind::DirectObjCClassName:
2094
+ case TypeReferenceKind::IndirectObjCClass:
2095
+ return nullptr ;
2091
2096
}
2092
2097
2093
2098
return nullptr ;
@@ -2117,6 +2122,67 @@ using ProtocolRecord = TargetProtocolRecord<InProcess>;
2117
2122
2118
2123
template <typename Runtime> class TargetGenericRequirementDescriptor ;
2119
2124
2125
+
2126
+ // / A referenc to a type.
2127
+ template <typename Runtime>
2128
+ struct TargetTypeReference {
2129
+ union {
2130
+ // / A direct reference to a nominal type descriptor.
2131
+ RelativeDirectPointer<TargetTypeContextDescriptor<Runtime>>
2132
+ DirectNominalTypeDescriptor;
2133
+
2134
+ // / An indirect reference to a nominal type descriptor.
2135
+ RelativeDirectPointer<
2136
+ ConstTargetMetadataPointer<Runtime, TargetTypeContextDescriptor>>
2137
+ IndirectNominalTypeDescriptor;
2138
+
2139
+ // / An indirect reference to an Objective-C class.
2140
+ RelativeDirectPointer<
2141
+ ConstTargetMetadataPointer<Runtime, TargetClassMetadata>>
2142
+ IndirectObjCClass;
2143
+
2144
+ // / A direct reference to an Objective-C class name.
2145
+ RelativeDirectPointer<const char >
2146
+ DirectObjCClassName;
2147
+ };
2148
+
2149
+ const TargetTypeContextDescriptor<Runtime> *
2150
+ getTypeContextDescriptor (TypeReferenceKind kind) const {
2151
+ switch (kind) {
2152
+ case TypeReferenceKind::DirectNominalTypeDescriptor:
2153
+ return DirectNominalTypeDescriptor;
2154
+
2155
+ case TypeReferenceKind::IndirectNominalTypeDescriptor:
2156
+ return *IndirectNominalTypeDescriptor;
2157
+
2158
+ case TypeReferenceKind::DirectObjCClassName:
2159
+ case TypeReferenceKind::IndirectObjCClass:
2160
+ return nullptr ;
2161
+ }
2162
+
2163
+ return nullptr ;
2164
+ }
2165
+
2166
+ #if SWIFT_OBJC_INTEROP
2167
+ // / If this type reference is one of the kinds that supports ObjC
2168
+ // / references,
2169
+ const TargetClassMetadata<Runtime> *
2170
+ getObjCClass (TypeReferenceKind kind) const ;
2171
+ #endif
2172
+
2173
+ const TargetClassMetadata<Runtime> * const *
2174
+ getIndirectObjCClass (TypeReferenceKind kind) const {
2175
+ assert (kind == TypeReferenceKind::IndirectObjCClass);
2176
+ return IndirectObjCClass.get ();
2177
+ }
2178
+
2179
+ const char *getDirectObjCClassName (TypeReferenceKind kind) const {
2180
+ assert (kind == TypeReferenceKind::DirectObjCClassName);
2181
+ return DirectObjCClassName.get ();
2182
+ }
2183
+ };
2184
+ using TypeReference = TargetTypeReference<InProcess>;
2185
+
2120
2186
// / The structure of a protocol conformance.
2121
2187
// /
2122
2188
// / This contains enough static information to recover the witness table for a
@@ -2153,21 +2219,7 @@ struct TargetProtocolConformanceDescriptor final
2153
2219
RelativeIndirectablePointer<ProtocolDescriptor> Protocol;
2154
2220
2155
2221
// Some description of the type that conforms to the protocol.
2156
- union {
2157
- // / A direct reference to a nominal type descriptor.
2158
- RelativeDirectPointer<TargetTypeContextDescriptor<Runtime>>
2159
- DirectNominalTypeDescriptor;
2160
-
2161
- // / An indirect reference to a nominal type descriptor.
2162
- RelativeDirectPointer<
2163
- ConstTargetMetadataPointer<Runtime, TargetTypeContextDescriptor>>
2164
- IndirectNominalTypeDescriptor;
2165
-
2166
- // / An indirect reference to the metadata.
2167
- RelativeDirectPointer<
2168
- ConstTargetMetadataPointer<Runtime, TargetClassMetadata>>
2169
- IndirectObjCClass;
2170
- };
2222
+ TargetTypeReference<Runtime> TypeRef;
2171
2223
2172
2224
// The conformance, or a generator function for the conformance.
2173
2225
union {
@@ -2187,45 +2239,24 @@ struct TargetProtocolConformanceDescriptor final
2187
2239
return Protocol;
2188
2240
}
2189
2241
2190
- TypeMetadataRecordKind getTypeKind () const {
2242
+ TypeReferenceKind getTypeKind () const {
2191
2243
return Flags.getTypeReferenceKind ();
2192
2244
}
2193
2245
2194
2246
typename ConformanceFlags::ConformanceKind getConformanceKind () const {
2195
2247
return Flags.getConformanceKind ();
2196
2248
}
2197
-
2198
- const TargetClassMetadata<Runtime> * const *getIndirectObjCClass () const {
2199
- switch (getTypeKind ()) {
2200
- case TypeMetadataRecordKind::IndirectObjCClass:
2201
- break ;
2202
2249
2203
- case TypeMetadataRecordKind::Reserved:
2204
- return nullptr ;
2250
+ const char *getDirectObjCClassName () const {
2251
+ return TypeRef.getDirectObjCClassName (getTypeKind ());
2252
+ }
2205
2253
2206
- case TypeMetadataRecordKind::DirectNominalTypeDescriptor:
2207
- case TypeMetadataRecordKind::IndirectNominalTypeDescriptor:
2208
- assert (false && " not indirect class object" );
2209
- }
2210
-
2211
- return IndirectObjCClass.get ();
2254
+ const TargetClassMetadata<Runtime> * const *getIndirectObjCClass () const {
2255
+ return TypeRef.getIndirectObjCClass (getTypeKind ());
2212
2256
}
2213
2257
2214
- const TargetTypeContextDescriptor<Runtime> *
2215
- getTypeContextDescriptor () const {
2216
- switch (getTypeKind ()) {
2217
- case TypeMetadataRecordKind::DirectNominalTypeDescriptor:
2218
- return DirectNominalTypeDescriptor;
2219
-
2220
- case TypeMetadataRecordKind::IndirectNominalTypeDescriptor:
2221
- return *IndirectNominalTypeDescriptor;
2222
-
2223
- case TypeMetadataRecordKind::Reserved:
2224
- case TypeMetadataRecordKind::IndirectObjCClass:
2225
- return nullptr ;
2226
- }
2227
-
2228
- return nullptr ;
2258
+ const TargetTypeContextDescriptor<Runtime> *getTypeContextDescriptor () const {
2259
+ return TypeRef.getTypeContextDescriptor (getTypeKind ());
2229
2260
}
2230
2261
2231
2262
// / Retrieve the context of a retroactive conformance.
@@ -2287,7 +2318,7 @@ struct TargetProtocolConformanceDescriptor final
2287
2318
// /
2288
2319
// / We currently check that the descriptor:
2289
2320
// /
2290
- // / 1. Has a valid TypeMetadataRecordKind .
2321
+ // / 1. Has a valid TypeReferenceKind .
2291
2322
// / 2. Has a valid conformance kind.
2292
2323
void verify () const LLVM_ATTRIBUTE_USED;
2293
2324
#endif
@@ -3344,7 +3375,7 @@ class TargetClassDescriptor final
3344
3375
return !Superclass.isNull ();
3345
3376
}
3346
3377
3347
- TypeMetadataRecordKind getSuperclassReferenceKind () const {
3378
+ TypeReferenceKind getSuperclassReferenceKind () const {
3348
3379
return getTypeContextDescriptorFlags ().class_getSuperclassReferenceKind ();
3349
3380
}
3350
3381
0 commit comments