@@ -82,7 +82,7 @@ bool RequirementSource::isAcceptableStorageKind(Kind kind,
82
82
switch (kind) {
83
83
case Explicit:
84
84
switch (storageKind) {
85
- case StorageKind::None :
85
+ case StorageKind::RootArchetype :
86
86
case StorageKind::TypeRepr:
87
87
case StorageKind::RequirementRepr:
88
88
return true ;
@@ -95,7 +95,7 @@ bool RequirementSource::isAcceptableStorageKind(Kind kind,
95
95
96
96
case Inferred:
97
97
switch (storageKind) {
98
- case StorageKind::None :
98
+ case StorageKind::RootArchetype :
99
99
case StorageKind::TypeRepr:
100
100
return true ;
101
101
@@ -108,7 +108,7 @@ bool RequirementSource::isAcceptableStorageKind(Kind kind,
108
108
109
109
case NestedTypeNameMatch:
110
110
switch (storageKind) {
111
- case StorageKind::None :
111
+ case StorageKind::RootArchetype :
112
112
return true ;
113
113
114
114
case StorageKind::TypeRepr:
@@ -124,7 +124,7 @@ bool RequirementSource::isAcceptableStorageKind(Kind kind,
124
124
case StorageKind::AssociatedTypeDecl:
125
125
return true ;
126
126
127
- case StorageKind::None :
127
+ case StorageKind::RootArchetype :
128
128
case StorageKind::TypeRepr:
129
129
case StorageKind::ProtocolDecl:
130
130
case StorageKind::ProtocolConformance:
@@ -138,7 +138,7 @@ bool RequirementSource::isAcceptableStorageKind(Kind kind,
138
138
case StorageKind::ProtocolDecl:
139
139
return true ;
140
140
141
- case StorageKind::None :
141
+ case StorageKind::RootArchetype :
142
142
case StorageKind::TypeRepr:
143
143
case StorageKind::ProtocolConformance:
144
144
case StorageKind::RequirementRepr:
@@ -152,7 +152,7 @@ bool RequirementSource::isAcceptableStorageKind(Kind kind,
152
152
case StorageKind::ProtocolConformance:
153
153
return true ;
154
154
155
- case StorageKind::None :
155
+ case StorageKind::RootArchetype :
156
156
case StorageKind::ProtocolDecl:
157
157
case StorageKind::TypeRepr:
158
158
case StorageKind::RequirementRepr:
@@ -164,9 +164,8 @@ bool RequirementSource::isAcceptableStorageKind(Kind kind,
164
164
165
165
const void *RequirementSource::getOpaqueStorage () const {
166
166
switch (storageKind) {
167
- case StorageKind::None:
168
- // Note: always null.
169
- return storage.typeRepr ;
167
+ case StorageKind::RootArchetype:
168
+ return storage.rootArchetype ;
170
169
171
170
case StorageKind::TypeRepr:
172
171
return storage.typeRepr ;
@@ -185,6 +184,13 @@ const void *RequirementSource::getOpaqueStorage() const {
185
184
}
186
185
}
187
186
187
+ const void *RequirementSource::getExtraOpaqueStorage () const {
188
+ if (numTrailingObjects (OverloadToken<PotentialArchetype *>()) == 1 )
189
+ return getTrailingObjects<PotentialArchetype *>()[0 ];
190
+
191
+ return nullptr ;
192
+ }
193
+
188
194
bool RequirementSource::isDerivedRequirement () const {
189
195
switch (kind) {
190
196
case Explicit:
@@ -228,110 +234,126 @@ bool RequirementSource::isDerivedViaConcreteConformance() const {
228
234
return false ;
229
235
}
230
236
231
- #define REQUIREMENT_SOURCE_FACTORY_BODY (SourceKind, Parent, Storage ) \
232
- llvm::FoldingSetNodeID nodeID; \
233
- Profile (nodeID, Kind::SourceKind, Parent, Storage); \
234
- \
235
- void *insertPos = nullptr ; \
236
- if (auto known = \
237
- builder.Impl->RequirementSources.FindNodeOrInsertPos(nodeID, \
238
- insertPos)) \
239
- return known; \
240
- \
241
- auto result = new RequirementSource(Kind::SourceKind, Parent, Storage); \
242
- builder.Impl->RequirementSources.InsertNode(result, insertPos); \
243
- return result
244
-
245
- #define REQUIREMENT_SOURCE_FACTORY_BODY_NOSTORAGE (SourceKind, Parent ) \
237
+ #define REQUIREMENT_SOURCE_FACTORY_BODY ( \
238
+ SourceKind, Parent, Storage, ExtraStorage, \
239
+ NumPotentialArchetypes) \
246
240
llvm::FoldingSetNodeID nodeID; \
247
- Profile (nodeID, Kind::SourceKind, Parent, nullptr ); \
241
+ Profile (nodeID, Kind::SourceKind, Parent, Storage, ExtraStorage); \
248
242
\
249
243
void *insertPos = nullptr ; \
250
244
if (auto known = \
251
245
builder.Impl->RequirementSources.FindNodeOrInsertPos(nodeID, \
252
246
insertPos)) \
253
247
return known; \
254
248
\
255
- auto result = new RequirementSource(Kind::SourceKind, Parent); \
249
+ unsigned size = \
250
+ totalSizeToAlloc<PotentialArchetype *>(NumPotentialArchetypes); \
251
+ void *mem = malloc(size); \
252
+ auto result = new (mem) RequirementSource(Kind::SourceKind, Parent, \
253
+ Storage); \
254
+ if (NumPotentialArchetypes > 0 ) \
255
+ result->getTrailingObjects<PotentialArchetype *>()[0 ] = ExtraStorage; \
256
256
builder.Impl->RequirementSources.InsertNode(result, insertPos); \
257
257
return result
258
258
259
259
const RequirementSource *RequirementSource::forAbstract (
260
260
PotentialArchetype *root) {
261
261
auto &builder = *root->getBuilder ();
262
- // FIXME: Store the root
263
- REQUIREMENT_SOURCE_FACTORY_BODY_NOSTORAGE (Explicit, nullptr );
262
+ REQUIREMENT_SOURCE_FACTORY_BODY (Explicit, nullptr , root, nullptr , 0 );
264
263
}
265
264
266
265
const RequirementSource *RequirementSource::forExplicit (
267
266
PotentialArchetype *root,
268
267
const TypeRepr *typeRepr) {
268
+ // If the type representation is NULL, we have an abstract requirement
269
+ // source.
270
+ if (!typeRepr)
271
+ return forAbstract (root);
272
+
269
273
auto &builder = *root->getBuilder ();
270
274
// FIXME: Store the root
271
- REQUIREMENT_SOURCE_FACTORY_BODY (Explicit, nullptr , typeRepr);
275
+ REQUIREMENT_SOURCE_FACTORY_BODY (Explicit, nullptr , typeRepr, root, 1 );
272
276
}
273
277
274
278
const RequirementSource *RequirementSource::forExplicit (
275
279
PotentialArchetype *root,
276
280
const RequirementRepr *requirementRepr) {
281
+ // If the requirement representation is NULL, we have an abstract requirement
282
+ // source.
283
+ if (!requirementRepr)
284
+ return forAbstract (root);
285
+
277
286
auto &builder = *root->getBuilder ();
278
- // FIXME: Store the root
279
- REQUIREMENT_SOURCE_FACTORY_BODY (Explicit, nullptr , requirementRepr);
287
+ REQUIREMENT_SOURCE_FACTORY_BODY (Explicit, nullptr , requirementRepr, root, 1 );
280
288
}
281
289
282
290
const RequirementSource *RequirementSource::forInferred (
283
291
PotentialArchetype *root,
284
292
const TypeRepr *typeRepr) {
285
293
auto &builder = *root->getBuilder ();
286
- // FIXME: Store the root
287
- REQUIREMENT_SOURCE_FACTORY_BODY (Inferred, nullptr , typeRepr);
294
+ REQUIREMENT_SOURCE_FACTORY_BODY (Inferred, nullptr , typeRepr, root, 1 );
288
295
}
289
296
290
297
const RequirementSource *RequirementSource::forRequirementSignature (
291
298
PotentialArchetype *root,
292
299
ProtocolDecl *protocol) {
293
300
auto &builder = *root->getBuilder ();
294
- // FIXME: Store the root
295
- REQUIREMENT_SOURCE_FACTORY_BODY (RequirementSignatureSelf, nullptr , protocol );
301
+ REQUIREMENT_SOURCE_FACTORY_BODY (RequirementSignatureSelf, nullptr , protocol,
302
+ root, 1 );
296
303
}
297
304
298
305
const RequirementSource *RequirementSource::forNestedTypeNameMatch (
299
306
PotentialArchetype *root) {
300
307
auto &builder = *root->getBuilder ();
301
- // FIXME: Store the root
302
- REQUIREMENT_SOURCE_FACTORY_BODY_NOSTORAGE (NestedTypeNameMatch, nullptr );
308
+ REQUIREMENT_SOURCE_FACTORY_BODY (NestedTypeNameMatch, nullptr , root, nullptr ,
309
+ 0 );
303
310
}
304
311
305
312
const RequirementSource *RequirementSource::viaAbstractProtocolRequirement (
306
313
GenericSignatureBuilder &builder,
307
314
ProtocolDecl *protocol) const {
308
- REQUIREMENT_SOURCE_FACTORY_BODY (ProtocolRequirement, this , protocol);
315
+ REQUIREMENT_SOURCE_FACTORY_BODY (ProtocolRequirement, this , protocol,
316
+ nullptr , 0 );
309
317
}
310
318
311
319
const RequirementSource *RequirementSource::viaSuperclass (
312
320
GenericSignatureBuilder &builder,
313
321
ProtocolConformance *conformance) const {
314
- REQUIREMENT_SOURCE_FACTORY_BODY (Superclass, this , conformance);
322
+ REQUIREMENT_SOURCE_FACTORY_BODY (Superclass, this , conformance, nullptr , 0 );
315
323
}
316
324
317
325
const RequirementSource *RequirementSource::viaConcrete (
318
326
GenericSignatureBuilder &builder,
319
327
ProtocolConformance *conformance) const {
320
- REQUIREMENT_SOURCE_FACTORY_BODY (Concrete, this , conformance);
328
+ REQUIREMENT_SOURCE_FACTORY_BODY (Concrete, this , conformance, nullptr , 0 );
321
329
}
322
330
323
331
const RequirementSource *RequirementSource::viaParent (
324
332
GenericSignatureBuilder &builder,
325
333
AssociatedTypeDecl *assocType) const {
326
- REQUIREMENT_SOURCE_FACTORY_BODY (Parent, this , assocType);
334
+ REQUIREMENT_SOURCE_FACTORY_BODY (Parent, this , assocType, nullptr , 0 );
327
335
}
328
336
329
- #undef REQUIREMENT_SOURCE_FACTORY_BODY_NOSTORAGE
330
337
#undef REQUIREMENT_SOURCE_FACTORY_BODY
331
338
339
+ PotentialArchetype *RequirementSource::getRootPotentialArchetype () const {
340
+ // / Find the root.
341
+ auto root = this ;
342
+ while (auto parent = root->parent )
343
+ root = parent;
344
+
345
+ // If the root archetype is in extra storage, grab it from there.
346
+ if (root->numTrailingObjects (OverloadToken<PotentialArchetype *>()) == 1 )
347
+ return root->getTrailingObjects <PotentialArchetype *>()[0 ];
348
+
349
+ // Otherwise, it's in inline storage.
350
+ assert (storageKind == StorageKind::RootArchetype);
351
+ return storage.rootArchetype ;
352
+ }
353
+
332
354
ProtocolDecl *RequirementSource::getProtocolDecl () const {
333
355
switch (storageKind) {
334
- case StorageKind::None :
356
+ case StorageKind::RootArchetype :
335
357
case StorageKind::TypeRepr:
336
358
case StorageKind::RequirementRepr:
337
359
return nullptr ;
@@ -405,6 +427,9 @@ void RequirementSource::print(llvm::raw_ostream &out,
405
427
if (parent) {
406
428
parent->print (out, srcMgr);
407
429
out << " -> " ;
430
+ } else {
431
+ auto pa = getRootPotentialArchetype ();
432
+ out << pa->getDebugName () << " : " ;
408
433
}
409
434
410
435
switch (kind) {
@@ -453,7 +478,7 @@ void RequirementSource::print(llvm::raw_ostream &out,
453
478
};
454
479
455
480
switch (storageKind) {
456
- case StorageKind::None :
481
+ case StorageKind::RootArchetype :
457
482
break ;
458
483
459
484
case StorageKind::TypeRepr:
0 commit comments