@@ -207,8 +207,9 @@ class ReflectionMetadataBuilder : public ConstantBuilder<> {
207
207
208
208
class AssociatedTypeMetadataBuilder : public ReflectionMetadataBuilder {
209
209
static const uint32_t AssociatedTypeRecordSize = 8 ;
210
- ArrayRef<const NominalTypeDecl *> NominalTypeDecls;
211
- ArrayRef<const ExtensionDecl *> ExtensionDecls;
210
+
211
+ llvm::PointerUnion<const NominalTypeDecl *, const ExtensionDecl *>
212
+ NominalOrExtensionDecl;
212
213
213
214
void addConformance (Module *ModuleContext,
214
215
CanType ConformingType,
@@ -247,19 +248,26 @@ class AssociatedTypeMetadataBuilder : public ReflectionMetadataBuilder {
247
248
}
248
249
}
249
250
251
+ const NominalTypeDecl *getNominalTypeDecl () const {
252
+ return NominalOrExtensionDecl.dyn_cast <const NominalTypeDecl *>();
253
+ }
254
+
255
+ const ExtensionDecl *getExtensionDecl () const {
256
+ return NominalOrExtensionDecl.dyn_cast <const ExtensionDecl *>();
257
+ }
258
+
250
259
void layout () {
251
- for (auto Decl : NominalTypeDecls) {
252
- PrettyStackTraceDecl DebugStack (" emitting associated type metadata" , Decl);
260
+ if (auto Decl = getNominalTypeDecl ()) {
261
+ PrettyStackTraceDecl DebugStack (" emitting associated type metadata" ,
262
+ Decl);
253
263
for (auto Conformance : Decl->getAllConformances ()) {
254
264
if (Conformance->isIncomplete ())
255
265
continue ;
256
266
addConformance (Decl->getModuleContext (),
257
267
Decl->getDeclaredType ()->getCanonicalType (),
258
268
Conformance);
259
269
}
260
- }
261
-
262
- for (auto Ext : ExtensionDecls) {
270
+ } else if (auto Ext = getExtensionDecl ()) {
263
271
PrettyStackTraceDecl DebugStack (" emitting associated type metadata" , Ext);
264
272
for (auto Conformance : Ext->getLocalConformances ()) {
265
273
auto Decl = Ext->getExtendedType ()->getNominalOrBoundGenericNominal ();
@@ -271,13 +279,16 @@ class AssociatedTypeMetadataBuilder : public ReflectionMetadataBuilder {
271
279
}
272
280
273
281
public:
274
- AssociatedTypeMetadataBuilder (IRGenModule &IGM,
275
- ArrayRef<const NominalTypeDecl *> NominalTypeDecls,
276
- ArrayRef<const ExtensionDecl *> ExtensionDecls,
277
- llvm::SetVector<CanType> &BuiltinTypes)
282
+ AssociatedTypeMetadataBuilder (IRGenModule &IGM, const NominalTypeDecl *Decl,
283
+ llvm::SetVector<CanType> &BuiltinTypes)
278
284
: ReflectionMetadataBuilder(IGM, BuiltinTypes),
279
- NominalTypeDecls (NominalTypeDecls),
280
- ExtensionDecls(ExtensionDecls) {}
285
+ NominalOrExtensionDecl (Decl) {}
286
+
287
+ AssociatedTypeMetadataBuilder (IRGenModule &IGM, const ExtensionDecl *Decl,
288
+ llvm::SetVector<CanType> &BuiltinTypes)
289
+ : ReflectionMetadataBuilder(IGM, BuiltinTypes),
290
+ NominalOrExtensionDecl(Decl) {}
291
+
281
292
282
293
llvm::GlobalVariable *emit () {
283
294
auto tempBase = std::unique_ptr<llvm::GlobalVariable>(
@@ -307,7 +318,7 @@ class AssociatedTypeMetadataBuilder : public ReflectionMetadataBuilder {
307
318
308
319
class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
309
320
const uint32_t fieldRecordSize = 12 ;
310
- ArrayRef< const NominalTypeDecl *> NominalTypeDecls ;
321
+ const NominalTypeDecl *NTD ;
311
322
312
323
void addFieldDecl (const ValueDecl *value, CanType type) {
313
324
reflection::FieldRecordFlags Flags;
@@ -330,77 +341,71 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
330
341
}
331
342
}
332
343
333
- void addDecl ( const NominalTypeDecl *decl ) {
344
+ void layout ( ) {
334
345
using swift::reflection::FieldDescriptorKind;
335
346
336
- PrettyStackTraceDecl DebugStack (" emitting field type metadata" , decl );
337
- auto type = decl ->getDeclaredType ()->getCanonicalType ();
338
- addTypeRef (decl ->getModuleContext (), type);
339
-
340
- switch (decl ->getKind ()) {
341
- case DeclKind::Class:
342
- case DeclKind::Struct: {
343
- auto properties = decl ->getStoredProperties ();
344
- addConstantInt16 (uint16_t (isa<StructDecl>(decl )
345
- ? FieldDescriptorKind::Struct
346
- : FieldDescriptorKind::Class));
347
- addConstantInt16 (fieldRecordSize);
348
- addConstantInt32 (std::distance (properties.begin (), properties.end ()));
349
- for (auto property : properties)
350
- addFieldDecl (property,
351
- property->getInterfaceType ()
347
+ PrettyStackTraceDecl DebugStack (" emitting field type metadata" , NTD );
348
+ auto type = NTD ->getDeclaredType ()->getCanonicalType ();
349
+ addTypeRef (NTD ->getModuleContext (), type);
350
+
351
+ switch (NTD ->getKind ()) {
352
+ case DeclKind::Class:
353
+ case DeclKind::Struct: {
354
+ auto properties = NTD ->getStoredProperties ();
355
+ addConstantInt16 (uint16_t (isa<StructDecl>(NTD )
356
+ ? FieldDescriptorKind::Struct
357
+ : FieldDescriptorKind::Class));
358
+ addConstantInt16 (fieldRecordSize);
359
+ addConstantInt32 (std::distance (properties.begin (), properties.end ()));
360
+ for (auto property : properties)
361
+ addFieldDecl (property,
362
+ property->getInterfaceType ()
352
363
->getCanonicalType ());
353
- break ;
354
- }
355
- case DeclKind::Enum: {
356
- auto enumDecl = cast<EnumDecl>(decl );
357
- auto cases = enumDecl->getAllElements ();
358
- addConstantInt16 (uint16_t (FieldDescriptorKind::Enum));
359
- addConstantInt16 (fieldRecordSize);
360
- addConstantInt32 (std::distance (cases.begin (), cases.end ()));
361
- for (auto enumCase : cases) {
362
- if (enumCase->hasArgumentType ()) {
363
- addFieldDecl (enumCase,
364
- enumCase->getArgumentInterfaceType ()
364
+ break ;
365
+ }
366
+ case DeclKind::Enum: {
367
+ auto enumDecl = cast<EnumDecl>(NTD );
368
+ auto cases = enumDecl->getAllElements ();
369
+ addConstantInt16 (uint16_t (FieldDescriptorKind::Enum));
370
+ addConstantInt16 (fieldRecordSize);
371
+ addConstantInt32 (std::distance (cases.begin (), cases.end ()));
372
+ for (auto enumCase : cases) {
373
+ if (enumCase->hasArgumentType ()) {
374
+ addFieldDecl (enumCase,
375
+ enumCase->getArgumentInterfaceType ()
365
376
->getCanonicalType ());
366
- } else {
367
- addFieldDecl (enumCase, CanType ());
377
+ } else {
378
+ addFieldDecl (enumCase, CanType ());
379
+ }
368
380
}
381
+ break ;
369
382
}
370
- break ;
371
- }
372
- case DeclKind::Protocol: {
373
- auto protocolDecl = cast<ProtocolDecl>(decl);
374
- FieldDescriptorKind Kind;
375
- if (protocolDecl->isObjC ())
376
- Kind = FieldDescriptorKind::ObjCProtocol;
377
- else if (protocolDecl->requiresClass ())
378
- Kind = FieldDescriptorKind::ClassProtocol;
379
- else
380
- Kind = FieldDescriptorKind::Protocol;
381
- addConstantInt16 (uint16_t (Kind));
382
- addConstantInt16 (fieldRecordSize);
383
- addConstantInt32 (0 );
384
- break ;
385
- }
386
- default :
387
- llvm_unreachable (" Not a nominal type" );
388
- break ;
389
- }
390
- }
391
-
392
- void layout () {
393
- for (auto decl : NominalTypeDecls) {
394
- addDecl (decl);
383
+ case DeclKind::Protocol: {
384
+ auto protocolDecl = cast<ProtocolDecl>(NTD);
385
+ FieldDescriptorKind Kind;
386
+ if (protocolDecl->isObjC ())
387
+ Kind = FieldDescriptorKind::ObjCProtocol;
388
+ else if (protocolDecl->requiresClass ())
389
+ Kind = FieldDescriptorKind::ClassProtocol;
390
+ else
391
+ Kind = FieldDescriptorKind::Protocol;
392
+ addConstantInt16 (uint16_t (Kind));
393
+ addConstantInt16 (fieldRecordSize);
394
+ addConstantInt32 (0 );
395
+ break ;
396
+ }
397
+ default :
398
+ llvm_unreachable (" Not a nominal type" );
399
+ break ;
395
400
}
396
401
}
397
402
398
403
public:
399
404
FieldTypeMetadataBuilder (IRGenModule &IGM,
400
- ArrayRef< const NominalTypeDecl *> NominalTypeDecls ,
405
+ const NominalTypeDecl * NTD ,
401
406
llvm::SetVector<CanType> &BuiltinTypes)
402
407
: ReflectionMetadataBuilder(IGM, BuiltinTypes),
403
- NominalTypeDecls (NominalTypeDecls ) {}
408
+ NTD (NTD ) {}
404
409
405
410
llvm::GlobalVariable *emit () {
406
411
@@ -776,46 +781,58 @@ llvm::Constant *IRGenModule::getAddrOfCaptureDescriptor(SILFunction &SILFn,
776
781
return llvm::ConstantExpr::getBitCast (var, CaptureDescriptorPtrTy);
777
782
}
778
783
779
- void IRGenModule::emitReflectionMetadataRecords () {
780
- auto DoNotHaveDecls = NominalTypeDecls.empty () && ExtensionDecls.empty ();
781
- if (!IRGen.Opts .EnableReflectionMetadata ||
782
- (!IRGen.Opts .EnableReflectionBuiltins && DoNotHaveDecls))
784
+ void IRGenModule::emitReflectionMetadata (const NominalTypeDecl *Decl) {
785
+ if (!IRGen.Opts .EnableReflectionMetadata )
783
786
return ;
784
787
785
- // We collect all referenced builtin types and emit records for them.
786
- // In practice only the standard library should directly reference
787
- // builtin types.
788
- //
789
- // FIXME: This metadata should be in the runtime instead.
790
788
llvm::SetVector<CanType> BuiltinTypes;
791
789
792
- {
793
- FieldTypeMetadataBuilder builder (*this , NominalTypeDecls, BuiltinTypes);
794
- auto var = builder.emit ();
795
- if (var)
796
- addUsedGlobal (var);
797
- }
790
+ emitFieldMetadataRecord (Decl);
791
+ emitAssociatedTypeMetadataRecord (Decl);
792
+ }
798
793
799
- {
800
- AssociatedTypeMetadataBuilder builder (* this ,
801
- NominalTypeDecls,
802
- ExtensionDecls,
803
- BuiltinTypes);
804
- auto var = builder.emit ();
805
- if (var)
806
- addUsedGlobal (var);
807
- }
794
+ void IRGenModule::emitAssociatedTypeMetadataRecord ( const NominalTypeDecl *Decl) {
795
+ if (!IRGen. Opts . EnableReflectionMetadata )
796
+ return ;
797
+
798
+ AssociatedTypeMetadataBuilder builder (* this , Decl, BuiltinTypes);
799
+ auto var = builder.emit ();
800
+ if (var)
801
+ addUsedGlobal (var);
802
+ }
808
803
809
- if (IRGen.Opts .EnableReflectionBuiltins ) {
810
- BuiltinTypes.insert (Context.TheNativeObjectType );
811
- BuiltinTypes.insert (Context.TheUnknownObjectType );
812
- BuiltinTypes.insert (Context.TheBridgeObjectType );
813
- BuiltinTypes.insert (Context.TheRawPointerType );
814
- BuiltinTypes.insert (Context.TheUnsafeValueBufferType );
804
+ void IRGenModule::emitAssociatedTypeMetadataRecord (const ExtensionDecl *Ext) {
805
+ if (!IRGen.Opts .EnableReflectionMetadata )
806
+ return ;
815
807
816
- BuiltinTypeMetadataBuilder builder (*this , BuiltinTypes);
817
- auto var = builder.emit ();
818
- if (var)
819
- addUsedGlobal (var);
820
- }
808
+ AssociatedTypeMetadataBuilder builder (*this , Ext, BuiltinTypes);
809
+ auto var = builder.emit ();
810
+ if (var)
811
+ addUsedGlobal (var);
812
+ }
813
+
814
+ void IRGenModule::emitBuiltinReflectionMetadata () {
815
+ if (!IRGen.Opts .EnableReflectionBuiltins )
816
+ return ;
817
+
818
+ BuiltinTypes.insert (Context.TheNativeObjectType );
819
+ BuiltinTypes.insert (Context.TheUnknownObjectType );
820
+ BuiltinTypes.insert (Context.TheBridgeObjectType );
821
+ BuiltinTypes.insert (Context.TheRawPointerType );
822
+ BuiltinTypes.insert (Context.TheUnsafeValueBufferType );
823
+
824
+ BuiltinTypeMetadataBuilder builder (*this , BuiltinTypes);
825
+ auto var = builder.emit ();
826
+ if (var)
827
+ addUsedGlobal (var);
828
+ }
829
+
830
+ void IRGenModule::emitFieldMetadataRecord (const NominalTypeDecl *Decl) {
831
+ if (!IRGen.Opts .EnableReflectionMetadata )
832
+ return ;
833
+
834
+ FieldTypeMetadataBuilder builder (*this , Decl, BuiltinTypes);
835
+ auto var = builder.emit ();
836
+ if (var)
837
+ addUsedGlobal (var);
821
838
}
0 commit comments