@@ -1688,7 +1688,7 @@ namespace {
16881688 VTable (IGM.getSILModule().lookUpVTable(getType())),
16891689 Resilient(IGM.hasResilientMetadata(Type, ResilienceExpansion::Minimal)) {
16901690
1691- if (getType ()->isForeign () || Type-> isForeignReferenceType () )
1691+ if (getType ()->isForeign ())
16921692 return ;
16931693
16941694 MetadataLayout = &IGM.getClassMetadataLayout (Type);
@@ -1719,7 +1719,6 @@ namespace {
17191719 }
17201720
17211721 void layout () {
1722- assert (!getType ()->isForeignReferenceType ());
17231722 super::layout ();
17241723 addVTable ();
17251724 addOverrideTable ();
@@ -2556,15 +2555,6 @@ void irgen::emitLazyTypeContextDescriptor(IRGenModule &IGM,
25562555void irgen::emitLazyTypeMetadata (IRGenModule &IGM, NominalTypeDecl *type) {
25572556 eraseExistingTypeContextDescriptor (IGM, type);
25582557
2559- // Special case, UFOs are opaque pointers for now.
2560- if (auto cd = dyn_cast<ClassDecl>(type)) {
2561- if (cd->isForeignReferenceType ()) {
2562- auto sd = cast<StructDecl>(type->getASTContext ().getOpaquePointerDecl ());
2563- emitStructMetadata (IGM, sd);
2564- return ;
2565- }
2566- }
2567-
25682558 if (requiresForeignTypeMetadata (type)) {
25692559 emitForeignTypeMetadata (IGM, type);
25702560 } else if (auto sd = dyn_cast<StructDecl>(type)) {
@@ -3245,12 +3235,7 @@ static void createNonGenericMetadataAccessFunction(IRGenModule &IGM,
32453235// / Emit the base-offset variable for the class.
32463236static void emitClassMetadataBaseOffset (IRGenModule &IGM,
32473237 ClassDecl *classDecl) {
3248- if (classDecl->isForeignReferenceType ()) {
3249- classDecl->getASTContext ().Diags .diagnose (
3250- classDecl->getLoc (), diag::foreign_reference_types_unsupported.ID ,
3251- {});
3252- exit (1 );
3253- }
3238+ assert (!classDecl->isForeignReferenceType ());
32543239
32553240 // Otherwise, we know the offset at compile time, even if our
32563241 // clients do not, so just emit a constant.
@@ -5444,6 +5429,9 @@ namespace {
54445429 ForeignClassMetadataBuilder (IRGenModule &IGM, ClassDecl *target,
54455430 ConstantStructBuilder &B)
54465431 : ForeignMetadataBuilderBase(IGM, target, B) {
5432+ assert (!getTargetType ()->isForeignReferenceType () &&
5433+ " foreign reference type metadata must be built with the ForeignReferenceTypeMetadataBuilder" );
5434+
54475435 if (IGM.getOptions ().LazyInitializeClassMetadata )
54485436 CanBeConstant = false ;
54495437 }
@@ -5532,6 +5520,61 @@ namespace {
55325520 B.addNullPointer (IGM.Int8PtrTy );
55335521 }
55345522 };
5523+
5524+ class ForeignReferenceTypeMetadataBuilder ;
5525+ class ForeignReferenceTypeMetadataBuilderBase :
5526+ public ForeignReferenceTypeMetadataVisitor<ForeignReferenceTypeMetadataBuilder> {
5527+ protected:
5528+ ConstantStructBuilder &B;
5529+
5530+ ForeignReferenceTypeMetadataBuilderBase (IRGenModule &IGM, ClassDecl *target,
5531+ ConstantStructBuilder &B)
5532+ : ForeignReferenceTypeMetadataVisitor(IGM, target), B(B) {}
5533+ };
5534+
5535+ // / A builder for ForeignReferenceTypeMetadata.
5536+ class ForeignReferenceTypeMetadataBuilder :
5537+ public ForeignMetadataBuilderBase<ForeignReferenceTypeMetadataBuilder,
5538+ ForeignReferenceTypeMetadataBuilderBase> {
5539+ public:
5540+ ForeignReferenceTypeMetadataBuilder (IRGenModule &IGM, ClassDecl *target,
5541+ ConstantStructBuilder &B)
5542+ : ForeignMetadataBuilderBase(IGM, target, B) {
5543+ assert (getTargetType ()->isForeignReferenceType () &&
5544+ " foreign reference type metadata build must be used on foreign reference types." );
5545+
5546+ if (IGM.getOptions ().LazyInitializeClassMetadata )
5547+ CanBeConstant = false ;
5548+ }
5549+
5550+ void emitInitializeMetadata (IRGenFunction &IGF, llvm::Value *metadata,
5551+ MetadataDependencyCollector *collector) {
5552+ llvm_unreachable (" Not implemented for foreign reference types." );
5553+ }
5554+
5555+ // Visitor methods.
5556+
5557+ void addValueWitnessTable () {
5558+ auto type = getTargetType ()->getCanonicalType ();
5559+ B.add (irgen::emitValueWitnessTable (IGM, type, false , false ).getValue ());
5560+ }
5561+
5562+ void addMetadataFlags () {
5563+ B.addInt (IGM.MetadataKindTy , (unsigned ) MetadataKind::ForeignReferenceType);
5564+ }
5565+
5566+ void addNominalTypeDescriptor () {
5567+ auto descriptor =
5568+ ClassContextDescriptorBuilder (this ->IGM , Target, RequireMetadata).emit ();
5569+ B.addSignedPointer (descriptor,
5570+ IGM.getOptions ().PointerAuth .TypeDescriptors ,
5571+ PointerAuthEntity::Special::TypeDescriptor);
5572+ }
5573+
5574+ void addReservedWord () {
5575+ B.addNullPointer (IGM.Int8PtrTy );
5576+ }
5577+ };
55355578
55365579 // / A builder for ForeignStructMetadata.
55375580 class ForeignStructMetadataBuilder :
@@ -5598,8 +5641,9 @@ bool irgen::requiresForeignTypeMetadata(CanType type) {
55985641
55995642bool irgen::requiresForeignTypeMetadata (NominalTypeDecl *decl) {
56005643 if (auto *clazz = dyn_cast<ClassDecl>(decl)) {
5601- assert (!clazz->isForeignReferenceType ());
5602-
5644+ if (clazz->isForeignReferenceType ())
5645+ return true ;
5646+
56035647 switch (clazz->getForeignClassKind ()) {
56045648 case ClassDecl::ForeignKind::Normal:
56055649 case ClassDecl::ForeignKind::RuntimeOnly:
@@ -5623,16 +5667,25 @@ void irgen::emitForeignTypeMetadata(IRGenModule &IGM, NominalTypeDecl *decl) {
56235667 init.setPacked (true );
56245668
56255669 if (auto classDecl = dyn_cast<ClassDecl>(decl)) {
5626- assert (classDecl->getForeignClassKind () == ClassDecl::ForeignKind::CFType ||
5627- classDecl->isForeignReferenceType ());
5670+ if (classDecl->isForeignReferenceType ()) {
5671+ ForeignReferenceTypeMetadataBuilder builder (IGM, classDecl, init);
5672+ builder.layout ();
56285673
5629- ForeignClassMetadataBuilder builder (IGM, classDecl, init);
5630- builder.layout ();
5674+ IGM.defineTypeMetadata (type, /* isPattern=*/ false ,
5675+ builder.canBeConstant (),
5676+ init.finishAndCreateFuture ());
5677+ builder.createMetadataAccessFunction ();
5678+ } else {
5679+ assert (classDecl->getForeignClassKind () == ClassDecl::ForeignKind::CFType);
56315680
5632- IGM.defineTypeMetadata (type, /* isPattern=*/ false ,
5633- builder.canBeConstant (),
5634- init.finishAndCreateFuture ());
5635- builder.createMetadataAccessFunction ();
5681+ ForeignClassMetadataBuilder builder (IGM, classDecl, init);
5682+ builder.layout ();
5683+
5684+ IGM.defineTypeMetadata (type, /* isPattern=*/ false ,
5685+ builder.canBeConstant (),
5686+ init.finishAndCreateFuture ());
5687+ builder.createMetadataAccessFunction ();
5688+ }
56365689 } else if (auto structDecl = dyn_cast<StructDecl>(decl)) {
56375690 assert (isa<ClangModuleUnit>(structDecl->getModuleScopeContext ()));
56385691
0 commit comments