@@ -2948,37 +2948,34 @@ IRGenModule::getAddrOfOriginalModuleContextDescriptor(StringRef Name) {
2948
2948
.first ->getValue ());
2949
2949
}
2950
2950
2951
- static void emitInitializeFieldOffsetVector (IRGenFunction &IGF,
2952
- SILType T,
2951
+ void IRGenFunction::emitInitializeFieldOffsetVector (SILType T,
2953
2952
llvm::Value *metadata,
2954
2953
bool isVWTMutable,
2955
2954
MetadataDependencyCollector *collector) {
2956
- auto &IGM = IGF.IGM ;
2957
-
2958
2955
auto *target = T.getNominalOrBoundGenericNominal ();
2959
2956
llvm::Value *fieldVector
2960
- = emitAddressOfFieldOffsetVector (IGF , metadata, target)
2957
+ = emitAddressOfFieldOffsetVector (* this , metadata, target)
2961
2958
.getAddress ();
2962
2959
2963
2960
// Collect the stored properties of the type.
2964
2961
unsigned numFields = getNumFields (target);
2965
2962
2966
2963
// Fill out an array with the field type metadata records.
2967
- Address fields = IGF. createAlloca (
2964
+ Address fields = createAlloca (
2968
2965
llvm::ArrayType::get (IGM.Int8PtrPtrTy , numFields),
2969
2966
IGM.getPointerAlignment (), " classFields" );
2970
- IGF. Builder .CreateLifetimeStart (fields, IGM.getPointerSize () * numFields);
2971
- fields = IGF. Builder .CreateStructGEP (fields, 0 , Size (0 ));
2967
+ Builder.CreateLifetimeStart (fields, IGM.getPointerSize () * numFields);
2968
+ fields = Builder.CreateStructGEP (fields, 0 , Size (0 ));
2972
2969
2973
2970
unsigned index = 0 ;
2974
2971
forEachField (IGM, target, [&](Field field) {
2975
2972
assert (field.isConcrete () &&
2976
2973
" initializing offset vector for type with missing member?" );
2977
2974
SILType propTy = field.getType (IGM, T);
2978
- llvm::Value *fieldLayout = emitTypeLayoutRef (IGF , propTy, collector);
2975
+ llvm::Value *fieldLayout = emitTypeLayoutRef (* this , propTy, collector);
2979
2976
Address fieldLayoutAddr =
2980
- IGF. Builder .CreateConstArrayGEP (fields, index, IGM.getPointerSize ());
2981
- IGF. Builder .CreateStore (fieldLayout, fieldLayoutAddr);
2977
+ Builder.CreateConstArrayGEP (fields, index, IGM.getPointerSize ());
2978
+ Builder.CreateStore (fieldLayout, fieldLayoutAddr);
2982
2979
++index;
2983
2980
});
2984
2981
assert (index == numFields);
@@ -3004,13 +3001,15 @@ static void emitInitializeFieldOffsetVector(IRGenFunction &IGF,
3004
3001
llvm_unreachable (" Emitting metadata init for fixed class metadata?" );
3005
3002
}
3006
3003
3007
- llvm::Value *dependency;
3008
-
3004
+ llvm::Value *dependency = nullptr ;
3005
+
3009
3006
switch (IGM.getClassMetadataStrategy (classDecl)) {
3010
3007
case ClassMetadataStrategy::Resilient:
3011
3008
case ClassMetadataStrategy::Singleton:
3012
3009
// Call swift_initClassMetadata().
3013
- dependency = IGF.Builder .CreateCall (
3010
+ assert (!classDecl->getObjCImplementationDecl ()
3011
+ && " Singleton/Resilient strategies not supported for objcImplementation" );
3012
+ dependency = Builder.CreateCall (
3014
3013
IGM.getInitClassMetadata2FunctionPointer (),
3015
3014
{metadata, IGM.getSize (Size (uintptr_t (flags))), numFieldsV,
3016
3015
fields.getAddress (), fieldVector});
@@ -3023,10 +3022,17 @@ static void emitInitializeFieldOffsetVector(IRGenFunction &IGF,
3023
3022
// Call swift_updateClassMetadata(). Note that the static metadata
3024
3023
// already references the superclass in this case, but we still want
3025
3024
// to ensure the superclass metadata is initialized first.
3026
- dependency = IGF.Builder .CreateCall (
3027
- IGM.getUpdateClassMetadata2FunctionPointer (),
3028
- {metadata, IGM.getSize (Size (uintptr_t (flags))), numFieldsV,
3029
- fields.getAddress (), fieldVector});
3025
+ if (classDecl->getObjCImplementationDecl ()) {
3026
+ Builder.CreateCall (
3027
+ IGM.getUpdatePureObjCClassMetadataFunctionPointer (),
3028
+ {metadata, IGM.getSize (Size (uintptr_t (flags))), numFieldsV,
3029
+ fields.getAddress (), fieldVector});
3030
+ } else {
3031
+ dependency = Builder.CreateCall (
3032
+ IGM.getUpdateClassMetadata2FunctionPointer (),
3033
+ {metadata, IGM.getSize (Size (uintptr_t (flags))), numFieldsV,
3034
+ fields.getAddress (), fieldVector});
3035
+ }
3030
3036
break ;
3031
3037
3032
3038
case ClassMetadataStrategy::Fixed:
@@ -3035,8 +3041,8 @@ static void emitInitializeFieldOffsetVector(IRGenFunction &IGF,
3035
3041
3036
3042
// Collect any possible dependency from initializing the class; generally
3037
3043
// this involves the superclass.
3038
- assert (collector);
3039
- collector->collect (IGF , dependency);
3044
+ if (collector && dependency)
3045
+ collector->collect (* this , dependency);
3040
3046
3041
3047
} else {
3042
3048
assert (isa<StructDecl>(target));
@@ -3047,12 +3053,12 @@ static void emitInitializeFieldOffsetVector(IRGenFunction &IGF,
3047
3053
flags |= StructLayoutFlags::IsVWTMutable;
3048
3054
3049
3055
// Call swift_initStructMetadata().
3050
- IGF. Builder .CreateCall (IGM.getInitStructMetadataFunctionPointer (),
3056
+ Builder.CreateCall (IGM.getInitStructMetadataFunctionPointer (),
3051
3057
{metadata, IGM.getSize (Size (uintptr_t (flags))),
3052
3058
numFieldsV, fields.getAddress (), fieldVector});
3053
3059
}
3054
3060
3055
- IGF. Builder .CreateLifetimeEnd (fields, IGM.getPointerSize () * numFields);
3061
+ Builder.CreateLifetimeEnd (fields, IGM.getPointerSize () * numFields);
3056
3062
}
3057
3063
3058
3064
static void emitInitializeFieldOffsetVectorWithLayoutString (
@@ -3314,8 +3320,8 @@ static void emitInitializeValueMetadata(IRGenFunction &IGF,
3314
3320
emitInitializeFieldOffsetVectorWithLayoutString (IGF, loweredTy, metadata,
3315
3321
isVWTMutable, collector);
3316
3322
} else {
3317
- emitInitializeFieldOffsetVector (IGF, loweredTy, metadata, isVWTMutable,
3318
- collector);
3323
+ IGF. emitInitializeFieldOffsetVector (loweredTy, metadata, isVWTMutable,
3324
+ collector);
3319
3325
}
3320
3326
} else {
3321
3327
assert (isa<EnumDecl>(nominalDecl));
@@ -3347,9 +3353,9 @@ static void emitInitializeClassMetadata(IRGenFunction &IGF,
3347
3353
3348
3354
// Set the superclass, fill out the field offset vector, and copy vtable
3349
3355
// entries, generic requirements and field offsets from superclasses.
3350
- emitInitializeFieldOffsetVector (IGF, loweredTy,
3351
- metadata, /* VWT is mutable*/ false ,
3352
- collector);
3356
+ IGF. emitInitializeFieldOffsetVector (loweredTy,
3357
+ metadata, /* VWT is mutable*/ false ,
3358
+ collector);
3353
3359
3354
3360
// Realizing the class with the ObjC runtime will copy back to the
3355
3361
// field offset globals for us; but if ObjC interop is disabled, we
@@ -3721,6 +3727,25 @@ createSingletonInitializationMetadataAccessFunction(IRGenModule &IGM,
3721
3727
[&](IRGenFunction &IGF,
3722
3728
DynamicMetadataRequest request,
3723
3729
llvm::Constant *cacheVariable) {
3730
+ if (auto CD = dyn_cast<ClassDecl>(typeDecl)) {
3731
+ if (CD->getObjCImplementationDecl ()) {
3732
+ // Use the Objective-C runtime symbol instead of the Swift one.
3733
+ llvm::Value *descriptor =
3734
+ IGF.IGM .getAddrOfObjCClass (CD, NotForDefinition);
3735
+
3736
+ // Make the ObjC runtime initialize the class.
3737
+ llvm::Value *initializedDescriptor =
3738
+ IGF.Builder .CreateCall (IGF.IGM .getFixedClassInitializationFn (),
3739
+ {descriptor});
3740
+
3741
+ // Turn the ObjC class into a valid Swift metadata pointer.
3742
+ auto response =
3743
+ IGF.Builder .CreateCall (IGF.IGM .getGetObjCClassMetadataFunctionPointer (),
3744
+ {initializedDescriptor});
3745
+ return MetadataResponse::forComplete (response);
3746
+ }
3747
+ }
3748
+
3724
3749
llvm::Value *descriptor =
3725
3750
IGF.IGM .getAddrOfTypeContextDescriptor (typeDecl, RequireMetadata);
3726
3751
auto responsePair =
@@ -4290,7 +4315,12 @@ namespace {
4290
4315
// Derive the RO-data.
4291
4316
llvm::Constant *data = asImpl ().getROData ();
4292
4317
4293
- if (!asImpl ().getFieldLayout ().hasObjCImplementation ()) {
4318
+ // Fixed-layout objcImpl classes should not have the Swift bit set.
4319
+ // Variable-layout objcImpl classes have the Swift bit set *temporarily*
4320
+ // so that the ObjC runtime realizes them as though they are Swift
4321
+ // classes, but the metadata update callback will clear the Swift bit
4322
+ // before the rest of the ObjC runtime starts looking at the class.
4323
+ if (!isPureObjC () || !hasFixedLayout ()) {
4294
4324
// Set a low bit to indicate this class has Swift metadata.
4295
4325
auto bit = llvm::ConstantInt::get (
4296
4326
IGM.IntPtrTy , asImpl ().getClassDataPointerHasSwiftMetadataBits ());
@@ -4369,6 +4399,9 @@ namespace {
4369
4399
if (IGM.getClassMetadataStrategy (Target) == ClassMetadataStrategy::Fixed)
4370
4400
return ;
4371
4401
4402
+ if (isPureObjC ())
4403
+ return ;
4404
+
4372
4405
emitMetadataCompletionFunction (
4373
4406
IGM, Target,
4374
4407
[&](IRGenFunction &IGF, llvm::Value *metadata,
@@ -4409,9 +4442,6 @@ namespace {
4409
4442
: super(IGM, theClass, builder, fieldLayout, vtable) {}
4410
4443
4411
4444
void addFieldOffset (VarDecl *var) {
4412
- if (asImpl ().getFieldLayout ().hasObjCImplementation ())
4413
- return ;
4414
-
4415
4445
addFixedFieldOffset (IGM, B, var, [](DeclContext *dc) {
4416
4446
return dc->getDeclaredTypeInContext ();
4417
4447
});
@@ -4443,18 +4473,12 @@ namespace {
4443
4473
: super(IGM, theClass, builder, fieldLayout) {}
4444
4474
4445
4475
void addFieldOffset (VarDecl *var) {
4446
- if (asImpl ().getFieldLayout ().hasObjCImplementation ())
4447
- return ;
4448
-
4449
4476
// Field offsets are either copied from the superclass or calculated
4450
4477
// at runtime.
4451
4478
B.addInt (IGM.SizeTy , 0 );
4452
4479
}
4453
4480
4454
4481
void addFieldOffsetPlaceholders (MissingMemberDecl *placeholder) {
4455
- if (asImpl ().getFieldLayout ().hasObjCImplementation ())
4456
- return ;
4457
-
4458
4482
for (unsigned i = 0 ,
4459
4483
e = placeholder->getNumberOfFieldOffsetVectorEntries ();
4460
4484
i < e; ++i) {
@@ -4955,9 +4979,6 @@ namespace {
4955
4979
}
4956
4980
4957
4981
void addFieldOffset (VarDecl *var) {
4958
- if (asImpl ().getFieldLayout ().hasObjCImplementation ())
4959
- return ;
4960
-
4961
4982
addFixedFieldOffset (IGM, B, var, [&](DeclContext *dc) {
4962
4983
return dc->mapTypeIntoContext (type);
4963
4984
});
0 commit comments