@@ -2585,12 +2585,31 @@ void irgen::emitLazyTypeContextDescriptor(IRGenModule &IGM,
2585
2585
RequireMetadata_t requireMetadata) {
2586
2586
eraseExistingTypeContextDescriptor (IGM, type);
2587
2587
2588
+ bool hasLayoutString = false ;
2589
+ auto lowered = getLoweredTypeInPrimaryContext (
2590
+ IGM, type->getDeclaredType ()->getCanonicalType ());
2591
+ auto &ti = IGM.getTypeInfo (lowered);
2592
+ auto *typeLayoutEntry =
2593
+ ti.buildTypeLayoutEntry (IGM, lowered, /* useStructLayouts*/ true );
2594
+ if (IGM.Context .LangOpts .hasFeature (Feature::LayoutStringValueWitnesses)) {
2595
+
2596
+ auto genericSig =
2597
+ lowered.getNominalOrBoundGenericNominal ()->getGenericSignature ();
2598
+ hasLayoutString = !!typeLayoutEntry->layoutString (IGM, genericSig);
2599
+ }
2600
+
2588
2601
if (auto sd = dyn_cast<StructDecl>(type)) {
2602
+ if (IGM.Context .LangOpts .hasFeature (Feature::LayoutStringValueWitnessesInstantiation)) {
2603
+ hasLayoutString |= requiresForeignTypeMetadata (type) ||
2604
+ needsSingletonMetadataInitialization (IGM, type) ||
2605
+ (type->isGenericContext () && !isa<FixedTypeInfo>(ti));
2606
+ }
2607
+
2589
2608
StructContextDescriptorBuilder (IGM, sd, requireMetadata,
2590
- /* hasLayoutString*/ false ).emit ();
2609
+ hasLayoutString).emit ();
2591
2610
} else if (auto ed = dyn_cast<EnumDecl>(type)) {
2592
2611
EnumContextDescriptorBuilder (IGM, ed, requireMetadata,
2593
- /* hasLayoutString*/ false )
2612
+ hasLayoutString)
2594
2613
.emit ();
2595
2614
} else if (auto cd = dyn_cast<ClassDecl>(type)) {
2596
2615
ClassContextDescriptorBuilder (IGM, cd, requireMetadata).emit ();
@@ -2873,8 +2892,8 @@ static void emitInitializeFieldOffsetVector(IRGenFunction &IGF,
2873
2892
}
2874
2893
2875
2894
static void emitInitializeFieldOffsetVectorWithLayoutString (
2876
- IRGenFunction &IGF, SILType T, llvm::Value *metadata, bool isVWTMutable,
2877
- MetadataDependencyCollector *collector) {
2895
+ IRGenFunction &IGF, SILType T, llvm::Value *metadata,
2896
+ bool isVWTMutable, MetadataDependencyCollector *collector) {
2878
2897
auto &IGM = IGF.IGM ;
2879
2898
assert (IGM.Context .LangOpts .hasFeature (
2880
2899
Feature::LayoutStringValueWitnessesInstantiation));
@@ -2892,38 +2911,68 @@ static void emitInitializeFieldOffsetVectorWithLayoutString(
2892
2911
2893
2912
// Fill out an array with the field type metadata records.
2894
2913
Address fieldsMetadata =
2895
- IGF.createAlloca (llvm::ArrayType::get (IGM.TypeMetadataPtrTy , numFields),
2914
+ IGF.createAlloca (llvm::ArrayType::get (IGM.Int8PtrPtrTy , numFields),
2896
2915
IGM.getPointerAlignment (), " fieldsMetadata" );
2897
2916
IGF.Builder .CreateLifetimeStart (fieldsMetadata,
2898
2917
IGM.getPointerSize () * numFields);
2899
2918
fieldsMetadata = IGF.Builder .CreateStructGEP (fieldsMetadata, 0 , Size (0 ));
2900
2919
2920
+ Address fieldTags =
2921
+ IGF.createAlloca (llvm::ArrayType::get (IGM.Int8Ty , numFields),
2922
+ Alignment (1 ), " fieldTags" );
2923
+ IGF.Builder .CreateLifetimeStart (fieldTags, Size (numFields));
2924
+ fieldTags = IGF.Builder .CreateStructGEP (fieldTags, 0 , Size (0 ));
2925
+
2901
2926
unsigned index = 0 ;
2902
2927
forEachField (IGM, target, [&](Field field) {
2903
2928
assert (field.isConcrete () &&
2904
2929
" initializing offset vector for type with missing member?" );
2905
2930
SILType propTy = field.getType (IGM, T);
2906
2931
llvm::Value *fieldMetatype;
2932
+ llvm::Value *fieldTag;
2907
2933
if (auto ownership = propTy.getReferenceStorageOwnership ()) {
2934
+ auto &ti = IGF.getTypeInfo (propTy.getObjectType ());
2935
+ auto *fixedTI = dyn_cast<FixedTypeInfo>(&ti);
2936
+ assert (fixedTI && " Reference should have fixed layout" );
2937
+ auto fixedSize = fixedTI->getFixedSize ();
2938
+ fieldMetatype = emitTypeLayoutRef (IGF, propTy, collector);
2908
2939
switch (*ownership) {
2940
+ case ReferenceOwnership::Unowned:
2941
+ fieldTag = llvm::Constant::getIntegerValue (
2942
+ IGM.Int8Ty , APInt (IGM.Int8Ty ->getBitWidth (),
2943
+ fixedSize == IGM.getPointerSize () ? 0x1 : 0x2 ));
2944
+ break ;
2909
2945
case ReferenceOwnership::Weak:
2910
- fieldMetatype = llvm::Constant::getIntegerValue (
2911
- IGM.TypeMetadataPtrTy , APInt (IGM.IntPtrTy ->getBitWidth (), 0x7 ));
2946
+ fieldTag = llvm::Constant::getIntegerValue (
2947
+ IGM.Int8Ty , APInt (IGM.Int8Ty ->getBitWidth (),
2948
+ fixedSize == IGM.getPointerSize () ? 0x3 : 0x4 ));
2912
2949
break ;
2913
- case ReferenceOwnership::Strong:
2914
- case ReferenceOwnership::Unowned:
2915
2950
case ReferenceOwnership::Unmanaged:
2916
- llvm_unreachable (" Unmanaged reference should have been lowered" );
2951
+ fieldTag = llvm::Constant::getIntegerValue (
2952
+ IGM.Int8Ty , APInt (IGM.Int8Ty ->getBitWidth (),
2953
+ fixedSize == IGM.getPointerSize () ? 0x5 : 0x6 ));
2954
+ break ;
2955
+ case ReferenceOwnership::Strong:
2956
+ llvm_unreachable (" Strong reference should have been lowered" );
2957
+ break ;
2917
2958
}
2918
2959
} else {
2960
+ fieldTag = llvm::Constant::getIntegerValue (
2961
+ IGM.Int8Ty , APInt (IGM.Int8Ty ->getBitWidth (), 0x0 ));
2919
2962
auto request = DynamicMetadataRequest::getNonBlocking (
2920
2963
MetadataState::LayoutComplete, collector);
2921
2964
fieldMetatype = IGF.emitTypeMetadataRefForLayout (propTy, request);
2965
+ fieldMetatype = IGF.Builder .CreateBitCast (fieldMetatype, IGM.Int8PtrPtrTy );
2922
2966
}
2923
2967
2968
+ Address fieldTagAddr = IGF.Builder .CreateConstArrayGEP (
2969
+ fieldTags, index, Size::forBits (IGM.Int8Ty ->getBitWidth ()));
2970
+ IGF.Builder .CreateStore (fieldTag, fieldTagAddr);
2971
+
2924
2972
Address fieldMetatypeAddr = IGF.Builder .CreateConstArrayGEP (
2925
2973
fieldsMetadata, index, IGM.getPointerSize ());
2926
2974
IGF.Builder .CreateStore (fieldMetatype, fieldMetatypeAddr);
2975
+
2927
2976
++index;
2928
2977
});
2929
2978
assert (index == numFields);
@@ -2937,8 +2986,10 @@ static void emitInitializeFieldOffsetVectorWithLayoutString(
2937
2986
IGF.Builder .CreateCall (
2938
2987
IGM.getInitStructMetadataWithLayoutStringFunctionPointer (),
2939
2988
{metadata, IGM.getSize (Size (uintptr_t (flags))), numFieldsV,
2940
- fieldsMetadata.getAddress (), fieldVector});
2989
+ fieldsMetadata.getAddress (), fieldTags. getAddress (), fieldVector});
2941
2990
2991
+ IGF.Builder .CreateLifetimeEnd (fieldTags,
2992
+ IGM.getPointerSize () * numFields);
2942
2993
IGF.Builder .CreateLifetimeEnd (fieldsMetadata,
2943
2994
IGM.getPointerSize () * numFields);
2944
2995
}
@@ -5133,8 +5184,10 @@ namespace {
5133
5184
return false ;
5134
5185
}
5135
5186
return !!getLayoutString () ||
5136
- IGM.Context .LangOpts .hasFeature (
5137
- Feature::LayoutStringValueWitnessesInstantiation);
5187
+ (IGM.Context .LangOpts .hasFeature (
5188
+ Feature::LayoutStringValueWitnessesInstantiation) &&
5189
+ (HasDependentVWT || HasDependentMetadata) &&
5190
+ !isa<FixedTypeInfo>(IGM.getTypeInfo (getLoweredType ())));
5138
5191
}
5139
5192
5140
5193
llvm::Constant *emitNominalTypeDescriptor () {
0 commit comments