@@ -2585,12 +2585,31 @@ void irgen::emitLazyTypeContextDescriptor(IRGenModule &IGM,
25852585 RequireMetadata_t requireMetadata) {
25862586 eraseExistingTypeContextDescriptor (IGM, type);
25872587
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+
25882601 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+
25892608 StructContextDescriptorBuilder (IGM, sd, requireMetadata,
2590- /* hasLayoutString*/ false ).emit ();
2609+ hasLayoutString).emit ();
25912610 } else if (auto ed = dyn_cast<EnumDecl>(type)) {
25922611 EnumContextDescriptorBuilder (IGM, ed, requireMetadata,
2593- /* hasLayoutString*/ false )
2612+ hasLayoutString)
25942613 .emit ();
25952614 } else if (auto cd = dyn_cast<ClassDecl>(type)) {
25962615 ClassContextDescriptorBuilder (IGM, cd, requireMetadata).emit ();
@@ -2873,8 +2892,8 @@ static void emitInitializeFieldOffsetVector(IRGenFunction &IGF,
28732892}
28742893
28752894static 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) {
28782897 auto &IGM = IGF.IGM ;
28792898 assert (IGM.Context .LangOpts .hasFeature (
28802899 Feature::LayoutStringValueWitnessesInstantiation));
@@ -2892,38 +2911,68 @@ static void emitInitializeFieldOffsetVectorWithLayoutString(
28922911
28932912 // Fill out an array with the field type metadata records.
28942913 Address fieldsMetadata =
2895- IGF.createAlloca (llvm::ArrayType::get (IGM.TypeMetadataPtrTy , numFields),
2914+ IGF.createAlloca (llvm::ArrayType::get (IGM.Int8PtrPtrTy , numFields),
28962915 IGM.getPointerAlignment (), " fieldsMetadata" );
28972916 IGF.Builder .CreateLifetimeStart (fieldsMetadata,
28982917 IGM.getPointerSize () * numFields);
28992918 fieldsMetadata = IGF.Builder .CreateStructGEP (fieldsMetadata, 0 , Size (0 ));
29002919
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+
29012926 unsigned index = 0 ;
29022927 forEachField (IGM, target, [&](Field field) {
29032928 assert (field.isConcrete () &&
29042929 " initializing offset vector for type with missing member?" );
29052930 SILType propTy = field.getType (IGM, T);
29062931 llvm::Value *fieldMetatype;
2932+ llvm::Value *fieldTag;
29072933 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);
29082939 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 ;
29092945 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 ));
29122949 break ;
2913- case ReferenceOwnership::Strong:
2914- case ReferenceOwnership::Unowned:
29152950 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 ;
29172958 }
29182959 } else {
2960+ fieldTag = llvm::Constant::getIntegerValue (
2961+ IGM.Int8Ty , APInt (IGM.Int8Ty ->getBitWidth (), 0x0 ));
29192962 auto request = DynamicMetadataRequest::getNonBlocking (
29202963 MetadataState::LayoutComplete, collector);
29212964 fieldMetatype = IGF.emitTypeMetadataRefForLayout (propTy, request);
2965+ fieldMetatype = IGF.Builder .CreateBitCast (fieldMetatype, IGM.Int8PtrPtrTy );
29222966 }
29232967
2968+ Address fieldTagAddr = IGF.Builder .CreateConstArrayGEP (
2969+ fieldTags, index, Size::forBits (IGM.Int8Ty ->getBitWidth ()));
2970+ IGF.Builder .CreateStore (fieldTag, fieldTagAddr);
2971+
29242972 Address fieldMetatypeAddr = IGF.Builder .CreateConstArrayGEP (
29252973 fieldsMetadata, index, IGM.getPointerSize ());
29262974 IGF.Builder .CreateStore (fieldMetatype, fieldMetatypeAddr);
2975+
29272976 ++index;
29282977 });
29292978 assert (index == numFields);
@@ -2937,8 +2986,10 @@ static void emitInitializeFieldOffsetVectorWithLayoutString(
29372986 IGF.Builder .CreateCall (
29382987 IGM.getInitStructMetadataWithLayoutStringFunctionPointer (),
29392988 {metadata, IGM.getSize (Size (uintptr_t (flags))), numFieldsV,
2940- fieldsMetadata.getAddress (), fieldVector});
2989+ fieldsMetadata.getAddress (), fieldTags. getAddress (), fieldVector});
29412990
2991+ IGF.Builder .CreateLifetimeEnd (fieldTags,
2992+ IGM.getPointerSize () * numFields);
29422993 IGF.Builder .CreateLifetimeEnd (fieldsMetadata,
29432994 IGM.getPointerSize () * numFields);
29442995}
@@ -5133,8 +5184,10 @@ namespace {
51335184 return false ;
51345185 }
51355186 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 ())));
51385191 }
51395192
51405193 llvm::Constant *emitNominalTypeDescriptor () {
0 commit comments