@@ -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 =
@@ -4275,6 +4300,9 @@ namespace {
4275
4300
llvm::Constant *getROData () { return emitClassPrivateData (IGM, Target); }
4276
4301
4277
4302
uint64_t getClassDataPointerHasSwiftMetadataBits () {
4303
+ // objcImpl classes should not have the Swift bit set.
4304
+ if (isPureObjC ())
4305
+ return 0 ;
4278
4306
return IGM.UseDarwinPreStableABIBit ? 1 : 2 ;
4279
4307
}
4280
4308
@@ -4290,15 +4318,13 @@ namespace {
4290
4318
// Derive the RO-data.
4291
4319
llvm::Constant *data = asImpl ().getROData ();
4292
4320
4293
- if (!asImpl ().getFieldLayout ().hasObjCImplementation ()) {
4294
- // Set a low bit to indicate this class has Swift metadata.
4295
- auto bit = llvm::ConstantInt::get (
4296
- IGM.IntPtrTy , asImpl ().getClassDataPointerHasSwiftMetadataBits ());
4321
+ // Set a low bit to indicate this class has Swift metadata.
4322
+ auto bit = llvm::ConstantInt::get (
4323
+ IGM.IntPtrTy , asImpl ().getClassDataPointerHasSwiftMetadataBits ());
4297
4324
4298
- // Emit data + bit.
4299
- data = llvm::ConstantExpr::getPtrToInt (data, IGM.IntPtrTy );
4300
- data = llvm::ConstantExpr::getAdd (data, bit);
4301
- }
4325
+ // Emit data + bit.
4326
+ data = llvm::ConstantExpr::getPtrToInt (data, IGM.IntPtrTy );
4327
+ data = llvm::ConstantExpr::getAdd (data, bit);
4302
4328
4303
4329
B.add (data);
4304
4330
}
@@ -4369,6 +4395,9 @@ namespace {
4369
4395
if (IGM.getClassMetadataStrategy (Target) == ClassMetadataStrategy::Fixed)
4370
4396
return ;
4371
4397
4398
+ if (isPureObjC ())
4399
+ return ;
4400
+
4372
4401
emitMetadataCompletionFunction (
4373
4402
IGM, Target,
4374
4403
[&](IRGenFunction &IGF, llvm::Value *metadata,
@@ -4409,9 +4438,6 @@ namespace {
4409
4438
: super(IGM, theClass, builder, fieldLayout, vtable) {}
4410
4439
4411
4440
void addFieldOffset (VarDecl *var) {
4412
- if (asImpl ().getFieldLayout ().hasObjCImplementation ())
4413
- return ;
4414
-
4415
4441
addFixedFieldOffset (IGM, B, var, [](DeclContext *dc) {
4416
4442
return dc->getDeclaredTypeInContext ();
4417
4443
});
@@ -4443,18 +4469,12 @@ namespace {
4443
4469
: super(IGM, theClass, builder, fieldLayout) {}
4444
4470
4445
4471
void addFieldOffset (VarDecl *var) {
4446
- if (asImpl ().getFieldLayout ().hasObjCImplementation ())
4447
- return ;
4448
-
4449
4472
// Field offsets are either copied from the superclass or calculated
4450
4473
// at runtime.
4451
4474
B.addInt (IGM.SizeTy , 0 );
4452
4475
}
4453
4476
4454
4477
void addFieldOffsetPlaceholders (MissingMemberDecl *placeholder) {
4455
- if (asImpl ().getFieldLayout ().hasObjCImplementation ())
4456
- return ;
4457
-
4458
4478
for (unsigned i = 0 ,
4459
4479
e = placeholder->getNumberOfFieldOffsetVectorEntries ();
4460
4480
i < e; ++i) {
@@ -4955,9 +4975,6 @@ namespace {
4955
4975
}
4956
4976
4957
4977
void addFieldOffset (VarDecl *var) {
4958
- if (asImpl ().getFieldLayout ().hasObjCImplementation ())
4959
- return ;
4960
-
4961
4978
addFixedFieldOffset (IGM, B, var, [&](DeclContext *dc) {
4962
4979
return dc->mapTypeIntoContext (type);
4963
4980
});
@@ -4980,6 +4997,7 @@ namespace {
4980
4997
}
4981
4998
4982
4999
uint64_t getClassDataPointerHasSwiftMetadataBits () {
5000
+ assert (!isPureObjC ());
4983
5001
return super::getClassDataPointerHasSwiftMetadataBits () | 2 ;
4984
5002
}
4985
5003
0 commit comments