@@ -113,6 +113,9 @@ class PrintTypeInfo {
113
113
case RecordKind::ClassExistential:
114
114
printHeader (" class_existential" );
115
115
break ;
116
+ case RecordKind::ExistentialMetatype:
117
+ printHeader (" existential_metatype" );
118
+ break ;
116
119
}
117
120
printBasic (TI);
118
121
printFields (RecordTI);
@@ -311,6 +314,26 @@ class ExistentialTypeInfoBuilder {
311
314
312
315
return builder.build ();
313
316
}
317
+
318
+ const TypeInfo *buildMetatype () {
319
+ if (Invalid)
320
+ return nullptr ;
321
+
322
+ if (ObjC) {
323
+ if (WitnessTableCount > 0 )
324
+ return nullptr ;
325
+
326
+ return TC.getTypeInfo (TC.getRawPointerTypeRef ());
327
+ }
328
+
329
+ RecordTypeInfoBuilder builder (TC, RecordKind::ExistentialMetatype);
330
+
331
+ builder.addField (" metadata" , TC.getRawPointerTypeRef ());
332
+ for (unsigned i = 0 ; i < WitnessTableCount; i++)
333
+ builder.addField (" wtable" , TC.getRawPointerTypeRef ());
334
+
335
+ return builder.build ();
336
+ }
314
337
};
315
338
316
339
}
@@ -360,6 +383,14 @@ TypeConverter::getThickFunctionTypeInfo() {
360
383
return ThickFunctionTI;
361
384
}
362
385
386
+ const TypeInfo *TypeConverter::getEmptyTypeInfo () {
387
+ if (EmptyTI != nullptr )
388
+ return EmptyTI;
389
+
390
+ EmptyTI = makeTypeInfo<TypeInfo>(TypeInfoKind::Builtin, 0 , 1 , 0 , 0 );
391
+ return EmptyTI;
392
+ }
393
+
363
394
const TypeRef *TypeConverter::getRawPointerTypeRef () {
364
395
if (RawPointerTR != nullptr )
365
396
return RawPointerTR;
@@ -384,6 +415,143 @@ const TypeRef *TypeConverter::getUnknownObjectTypeRef() {
384
415
return UnknownObjectTR;
385
416
}
386
417
418
+ enum class MetatypeRepresentation : unsigned {
419
+ Thin,
420
+ Thick,
421
+ Unknown
422
+ };
423
+
424
+ MetatypeRepresentation combineRepresentations (MetatypeRepresentation rep1,
425
+ MetatypeRepresentation rep2) {
426
+ if (rep1 == rep2)
427
+ return rep1;
428
+
429
+ if (rep1 == MetatypeRepresentation::Unknown ||
430
+ rep2 == MetatypeRepresentation::Unknown)
431
+ return MetatypeRepresentation::Unknown;
432
+
433
+ if (rep1 == MetatypeRepresentation::Thick ||
434
+ rep2 == MetatypeRepresentation::Thick)
435
+ return MetatypeRepresentation::Thick;
436
+
437
+ return MetatypeRepresentation::Thin;
438
+ }
439
+
440
+ class HasSingletonMetatype
441
+ : public TypeRefVisitor<HasSingletonMetatype, MetatypeRepresentation> {
442
+ TypeRefBuilder &Builder;
443
+
444
+ public:
445
+ HasSingletonMetatype (TypeRefBuilder &Builder) : Builder(Builder) {}
446
+
447
+ using TypeRefVisitor<HasSingletonMetatype, MetatypeRepresentation>::visit;
448
+
449
+ MetatypeRepresentation visitBuiltinTypeRef (const BuiltinTypeRef *B) {
450
+ return MetatypeRepresentation::Thin;
451
+ }
452
+
453
+ MetatypeRepresentation visitAnyNominalTypeRef (const TypeRef *TR) {
454
+ const FieldDescriptor *FD = Builder.getFieldTypeInfo (TR);
455
+ if (FD == nullptr )
456
+ return MetatypeRepresentation::Unknown;
457
+
458
+ switch (FD->Kind ) {
459
+ case FieldDescriptorKind::Class:
460
+ return MetatypeRepresentation::Thick;
461
+
462
+ case FieldDescriptorKind::Struct:
463
+ case FieldDescriptorKind::Enum:
464
+ return MetatypeRepresentation::Thin;
465
+
466
+ case FieldDescriptorKind::ObjCProtocol:
467
+ case FieldDescriptorKind::ClassProtocol:
468
+ case FieldDescriptorKind::Protocol:
469
+ return MetatypeRepresentation::Unknown;
470
+ }
471
+ }
472
+
473
+ MetatypeRepresentation visitNominalTypeRef (const NominalTypeRef *N) {
474
+ return visitAnyNominalTypeRef (N);
475
+ }
476
+
477
+ MetatypeRepresentation visitBoundGenericTypeRef (const BoundGenericTypeRef *BG) {
478
+ return visitAnyNominalTypeRef (BG);
479
+ }
480
+
481
+ MetatypeRepresentation visitTupleTypeRef (const TupleTypeRef *T) {
482
+ auto result = MetatypeRepresentation::Thin;
483
+ for (auto Element : T->getElements ())
484
+ result = combineRepresentations (result, visit (Element));
485
+ return result;
486
+ }
487
+
488
+ MetatypeRepresentation visitFunctionTypeRef (const FunctionTypeRef *F) {
489
+ auto result = visit (F->getResult ());
490
+ for (auto Arg : F->getArguments ())
491
+ result = combineRepresentations (result, visit (Arg));
492
+ return result;
493
+ }
494
+
495
+ MetatypeRepresentation visitProtocolTypeRef (const ProtocolTypeRef *P) {
496
+ return MetatypeRepresentation::Thin;
497
+ }
498
+
499
+ MetatypeRepresentation
500
+ visitProtocolCompositionTypeRef (const ProtocolCompositionTypeRef *PC) {
501
+ return MetatypeRepresentation::Thin;
502
+ }
503
+
504
+ MetatypeRepresentation visitMetatypeTypeRef (const MetatypeTypeRef *M) {
505
+ if (M->wasAbstract ())
506
+ return MetatypeRepresentation::Thick;
507
+ return visit (M->getInstanceType ());
508
+ }
509
+
510
+ MetatypeRepresentation
511
+ visitExistentialMetatypeTypeRef (const ExistentialMetatypeTypeRef *EM) {
512
+ return MetatypeRepresentation::Thin;
513
+ }
514
+
515
+ MetatypeRepresentation
516
+ visitGenericTypeParameterTypeRef (const GenericTypeParameterTypeRef *GTP) {
517
+ assert (false && " Must have concrete TypeRef" );
518
+ return MetatypeRepresentation::Unknown;
519
+ }
520
+
521
+ MetatypeRepresentation
522
+ visitDependentMemberTypeRef (const DependentMemberTypeRef *DM) {
523
+ assert (false && " Must have concrete TypeRef" );
524
+ return MetatypeRepresentation::Unknown;
525
+ }
526
+
527
+ MetatypeRepresentation
528
+ visitForeignClassTypeRef (const ForeignClassTypeRef *F) {
529
+ return MetatypeRepresentation::Unknown;
530
+ }
531
+
532
+ MetatypeRepresentation visitObjCClassTypeRef (const ObjCClassTypeRef *OC) {
533
+ return MetatypeRepresentation::Unknown;
534
+ }
535
+
536
+ MetatypeRepresentation
537
+ visitUnownedStorageTypeRef (const UnownedStorageTypeRef *US) {
538
+ return MetatypeRepresentation::Unknown;
539
+ }
540
+
541
+ MetatypeRepresentation visitWeakStorageTypeRef (const WeakStorageTypeRef *WS) {
542
+ return MetatypeRepresentation::Unknown;
543
+ }
544
+
545
+ MetatypeRepresentation
546
+ visitUnmanagedStorageTypeRef (const UnmanagedStorageTypeRef *US) {
547
+ return MetatypeRepresentation::Unknown;
548
+ }
549
+
550
+ MetatypeRepresentation visitOpaqueTypeRef (const OpaqueTypeRef *O) {
551
+ return MetatypeRepresentation::Unknown;
552
+ }
553
+ };
554
+
387
555
class LowerType
388
556
: public TypeRefVisitor<LowerType, const TypeInfo *> {
389
557
TypeConverter &TC;
@@ -508,14 +676,31 @@ class LowerType
508
676
}
509
677
510
678
const TypeInfo *visitMetatypeTypeRef (const MetatypeTypeRef *M) {
511
- // FIXME
512
- return nullptr ;
679
+ switch (HasSingletonMetatype (TC.getBuilder ()).visit (M)) {
680
+ case MetatypeRepresentation::Unknown:
681
+ return nullptr ;
682
+ case MetatypeRepresentation::Thin:
683
+ return TC.getEmptyTypeInfo ();
684
+ case MetatypeRepresentation::Thick:
685
+ return TC.getTypeInfo (TC.getRawPointerTypeRef ());
686
+ }
513
687
}
514
688
515
689
const TypeInfo *
516
690
visitExistentialMetatypeTypeRef (const ExistentialMetatypeTypeRef *EM) {
517
- // FIXME
518
- return nullptr ;
691
+ ExistentialTypeInfoBuilder builder (TC);
692
+ auto *TR = EM->getInstanceType ();
693
+
694
+ if (auto *P = dyn_cast<ProtocolTypeRef>(TR)) {
695
+ builder.addProtocol (P);
696
+ } else if (auto *PC = dyn_cast<ProtocolCompositionTypeRef>(TR)) {
697
+ for (auto *P : PC->getProtocols ())
698
+ builder.addProtocol (P);
699
+ } else {
700
+ return nullptr ;
701
+ }
702
+
703
+ return builder.buildMetatype ();
519
704
}
520
705
521
706
const TypeInfo *
@@ -594,7 +779,7 @@ class LowerType
594
779
return visitAnyStorageTypeRef (US, ReferenceKind::Unmanaged);
595
780
}
596
781
597
- const TypeInfo *visitOpaqueTypeRef (const OpaqueTypeRef *Op ) {
782
+ const TypeInfo *visitOpaqueTypeRef (const OpaqueTypeRef *O ) {
598
783
assert (false && " Can't lower opaque TypeRef" );
599
784
return nullptr ;
600
785
}
0 commit comments