@@ -227,39 +227,24 @@ class ReflectionMetadataBuilder : public ConstantBuilder<> {
227
227
class AssociatedTypeMetadataBuilder : public ReflectionMetadataBuilder {
228
228
static const uint32_t AssociatedTypeRecordSize = 8 ;
229
229
230
- llvm::PointerUnion< const NominalTypeDecl *, const ExtensionDecl *>
231
- NominalOrExtensionDecl ;
230
+ const ProtocolConformance *Conformance;
231
+ ArrayRef<std::pair<StringRef, CanType>> AssociatedTypes ;
232
232
233
- void addConformance (Module *ModuleContext,
234
- CanType ConformingType,
235
- const ProtocolConformance *Conformance) {
236
- SmallVector<std::pair<StringRef, CanType>, 2 > AssociatedTypes;
237
-
238
- auto collectTypeWitness = [&](const AssociatedTypeDecl *AssocTy,
239
- const Substitution &Sub,
240
- const TypeDecl *TD) -> bool {
241
-
242
- auto Subst = ArchetypeBuilder::mapTypeOutOfContext (
243
- Conformance->getDeclContext (), Sub.getReplacement ());
244
-
245
- AssociatedTypes.push_back ({
246
- AssocTy->getNameStr (),
247
- Subst->getCanonicalType ()
248
- });
249
- return false ;
250
- };
233
+ void layout () {
234
+ // If the conforming type is generic, we just want to emit the
235
+ // unbound generic type here.
236
+ auto *Nominal = Conformance->getInterfaceType ()->getAnyNominal ();
237
+ assert (Nominal && " Structural conformance?" );
251
238
252
- Conformance->forEachTypeWitness (/* resolver*/ nullptr , collectTypeWitness);
239
+ PrettyStackTraceDecl DebugStack (" emitting associated type metadata" ,
240
+ Nominal);
253
241
254
- // If there are no associated types, don't bother emitting any
255
- // metadata.
256
- if (AssociatedTypes.empty ())
257
- return ;
242
+ auto *M = IGM.getSILModule ().getSwiftModule ();
258
243
259
- addTypeRef (ModuleContext, ConformingType );
244
+ addTypeRef (M, Nominal-> getDeclaredType ()-> getCanonicalType () );
260
245
261
246
auto ProtoTy = Conformance->getProtocol ()->getDeclaredType ();
262
- addTypeRef (ModuleContext , ProtoTy->getCanonicalType ());
247
+ addTypeRef (M , ProtoTy->getCanonicalType ());
263
248
264
249
addConstantInt32 (AssociatedTypes.size ());
265
250
addConstantInt32 (AssociatedTypeRecordSize);
@@ -268,47 +253,16 @@ class AssociatedTypeMetadataBuilder : public ReflectionMetadataBuilder {
268
253
auto NameGlobal = IGM.getAddrOfStringForTypeRef (AssocTy.first );
269
254
addRelativeAddress (NameGlobal);
270
255
addBuiltinTypeRefs (AssocTy.second );
271
- addTypeRef (ModuleContext, AssocTy.second );
272
- }
273
- }
274
-
275
- const NominalTypeDecl *getNominalTypeDecl () const {
276
- return NominalOrExtensionDecl.dyn_cast <const NominalTypeDecl *>();
277
- }
278
-
279
- const ExtensionDecl *getExtensionDecl () const {
280
- return NominalOrExtensionDecl.dyn_cast <const ExtensionDecl *>();
281
- }
282
-
283
- void layout () {
284
- if (auto Decl = getNominalTypeDecl ()) {
285
- PrettyStackTraceDecl DebugStack (" emitting associated type metadata" ,
286
- Decl);
287
- for (auto Conformance : Decl->getAllConformances ()) {
288
- if (Conformance->isIncomplete ())
289
- continue ;
290
- addConformance (Decl->getModuleContext (),
291
- Decl->getDeclaredType ()->getCanonicalType (),
292
- Conformance);
293
- }
294
- } else if (auto Ext = getExtensionDecl ()) {
295
- PrettyStackTraceDecl DebugStack (" emitting associated type metadata" , Ext);
296
- for (auto Conformance : Ext->getLocalConformances ()) {
297
- auto Decl = Ext->getExtendedType ()->getNominalOrBoundGenericNominal ();
298
- addConformance (Ext->getDeclContext ()->getParentModule (),
299
- Decl->getDeclaredType ()->getCanonicalType (),
300
- Conformance);
301
- }
256
+ addTypeRef (M, AssocTy.second );
302
257
}
303
258
}
304
259
305
260
public:
306
- AssociatedTypeMetadataBuilder (IRGenModule &IGM, const NominalTypeDecl *Decl)
307
- : ReflectionMetadataBuilder(IGM), NominalOrExtensionDecl(Decl) {}
308
-
309
- AssociatedTypeMetadataBuilder (IRGenModule &IGM, const ExtensionDecl *Decl)
310
- : ReflectionMetadataBuilder(IGM), NominalOrExtensionDecl(Decl) {}
311
-
261
+ AssociatedTypeMetadataBuilder (IRGenModule &IGM,
262
+ const ProtocolConformance *Conformance,
263
+ ArrayRef<std::pair<StringRef, CanType>> AssociatedTypes)
264
+ : ReflectionMetadataBuilder(IGM), Conformance(Conformance),
265
+ AssociatedTypes (AssociatedTypes) {}
312
266
313
267
llvm::GlobalVariable *emit () {
314
268
auto tempBase = std::unique_ptr<llvm::GlobalVariable>(
@@ -848,29 +802,35 @@ IRGenModule::getAddrOfCaptureDescriptor(SILFunction &Caller,
848
802
return llvm::ConstantExpr::getBitCast (var, CaptureDescriptorPtrTy);
849
803
}
850
804
851
- void IRGenModule::emitReflectionMetadata (const NominalTypeDecl *Decl) {
805
+ void IRGenModule::
806
+ emitAssociatedTypeMetadataRecord (const ProtocolConformance *Conformance) {
852
807
if (!IRGen.Opts .EnableReflectionMetadata )
853
808
return ;
854
809
855
- emitFieldMetadataRecord (Decl);
856
- emitAssociatedTypeMetadataRecord (Decl);
857
- }
810
+ SmallVector<std::pair<StringRef, CanType>, 2 > AssociatedTypes;
858
811
859
- void IRGenModule::emitAssociatedTypeMetadataRecord (const NominalTypeDecl *Decl){
860
- if (!IRGen. Opts . EnableReflectionMetadata )
861
- return ;
812
+ auto collectTypeWitness = [&] (const AssociatedTypeDecl *AssocTy,
813
+ const Substitution &Sub,
814
+ const TypeDecl *TD) -> bool {
862
815
863
- AssociatedTypeMetadataBuilder builder (*this , Decl);
864
- auto var = builder.emit ();
865
- if (var)
866
- addUsedGlobal (var);
867
- }
816
+ auto Subst = ArchetypeBuilder::mapTypeOutOfContext (
817
+ Conformance->getDeclContext (), Sub.getReplacement ());
868
818
869
- void IRGenModule::emitAssociatedTypeMetadataRecord (const ExtensionDecl *Ext) {
870
- if (!IRGen.Opts .EnableReflectionMetadata )
819
+ AssociatedTypes.push_back ({
820
+ AssocTy->getNameStr (),
821
+ Subst->getCanonicalType ()
822
+ });
823
+ return false ;
824
+ };
825
+
826
+ Conformance->forEachTypeWitness (/* resolver*/ nullptr , collectTypeWitness);
827
+
828
+ // If there are no associated types, don't bother emitting any
829
+ // metadata.
830
+ if (AssociatedTypes.empty ())
871
831
return ;
872
832
873
- AssociatedTypeMetadataBuilder builder (*this , Ext );
833
+ AssociatedTypeMetadataBuilder builder (*this , Conformance, AssociatedTypes );
874
834
auto var = builder.emit ();
875
835
if (var)
876
836
addUsedGlobal (var);
0 commit comments