Merge remote-tracking branch 'origin/master' into master-llvm-swift5-transition

This commit is contained in:
swift-ci
2018-03-04 01:18:05 -08:00
35 changed files with 1349 additions and 778 deletions

View File

@@ -1021,6 +1021,10 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
/// Only meaningful for class descriptors. /// Only meaningful for class descriptors.
Class_SuperclassReferenceKind = 12, Class_SuperclassReferenceKind = 12,
Class_SuperclassReferenceKind_width = 2, Class_SuperclassReferenceKind_width = 2,
/// Whether the immediate class members in this metadata are allocated
/// at negative offsets. For now, we don't use this.
Class_AreImmediateMembersNegative = 11,
}; };
public: public:
@@ -1037,6 +1041,9 @@ public:
FLAGSET_DEFINE_FLAG_ACCESSORS(Class_HasResilientSuperclass, FLAGSET_DEFINE_FLAG_ACCESSORS(Class_HasResilientSuperclass,
class_hasResilientSuperclass, class_hasResilientSuperclass,
class_setHasResilientSuperclass) class_setHasResilientSuperclass)
FLAGSET_DEFINE_FLAG_ACCESSORS(Class_AreImmediateMembersNegative,
class_areImmediateMembersNegative,
class_setAreImmediateMembersNegative)
FLAGSET_DEFINE_FIELD_ACCESSORS(Class_SuperclassReferenceKind, FLAGSET_DEFINE_FIELD_ACCESSORS(Class_SuperclassReferenceKind,
Class_SuperclassReferenceKind_width, Class_SuperclassReferenceKind_width,

View File

@@ -60,7 +60,7 @@ protected:
if (value) { if (value) {
Bits |= maskFor<Bit>(); Bits |= maskFor<Bit>();
} else { } else {
Bits |= ~maskFor<Bit>(); Bits &= ~maskFor<Bit>();
} }
} }

View File

@@ -233,7 +233,7 @@ public:
return StoredPointer(); return StoredPointer();
auto classMeta = cast<TargetClassMetadata<Runtime>>(meta); auto classMeta = cast<TargetClassMetadata<Runtime>>(meta);
return classMeta->SuperClass; return classMeta->Superclass;
} }
/// Given a remote pointer to class metadata, attempt to discover its class /// Given a remote pointer to class metadata, attempt to discover its class
@@ -537,32 +537,24 @@ public:
/// ///
/// The offset is in units of words, from the start of the class's /// The offset is in units of words, from the start of the class's
/// metadata. /// metadata.
llvm::Optional<uint32_t> llvm::Optional<int32_t>
readGenericArgsOffset(MetadataRef metadata, readGenericArgsOffset(MetadataRef metadata,
ContextDescriptorRef descriptor) { ContextDescriptorRef descriptor) {
switch (descriptor->getKind()) { switch (descriptor->getKind()) {
case ContextDescriptorKind::Class: { case ContextDescriptorKind::Class: {
auto type = cast<TargetClassDescriptor<Runtime>>(descriptor); auto type = cast<TargetClassDescriptor<Runtime>>(descriptor);
auto *classMetadata = dyn_cast<TargetClassMetadata<Runtime>>(metadata); if (!type->hasResilientSuperclass())
if (!classMetadata) return type->getNonResilientGenericArgumentOffset();
auto bounds = readMetadataBoundsOfSuperclass(descriptor);
if (!bounds)
return llvm::None; return llvm::None;
if (!classMetadata->SuperClass) bounds->adjustForSubclass(type->areImmediateMembersNegative(),
return type->getGenericArgumentOffset(nullptr, nullptr); type->NumImmediateMembers);
auto superMetadata = readMetadata(classMetadata->SuperClass); return bounds->ImmediateMembersOffset / sizeof(StoredPointer);
if (!superMetadata)
return llvm::None;
auto superClassMetadata =
dyn_cast<TargetClassMetadata<Runtime>>(superMetadata);
if (!superClassMetadata)
return llvm::None;
auto result =
type->getGenericArgumentOffset(classMetadata, superClassMetadata);
return result;
} }
case ContextDescriptorKind::Enum: { case ContextDescriptorKind::Enum: {
@@ -580,6 +572,76 @@ public:
} }
} }
using ClassMetadataBounds = TargetClassMetadataBounds<Runtime>;
// This follows computeMetadataBoundsForSuperclass.
llvm::Optional<ClassMetadataBounds>
readMetadataBoundsOfSuperclass(ContextDescriptorRef subclassRef) {
auto subclass = cast<TargetClassDescriptor<Runtime>>(subclassRef);
auto rawSuperclass =
resolveNullableRelativeField(subclassRef, subclass->Superclass);
if (!rawSuperclass) {
return ClassMetadataBounds::forSwiftRootClass();
}
return forTypeReference<ClassMetadataBounds>(
subclass->getSuperclassReferenceKind(), *rawSuperclass,
[&](ContextDescriptorRef superclass)
-> llvm::Optional<ClassMetadataBounds> {
if (!isa<TargetClassDescriptor<Runtime>>(superclass))
return llvm::None;
return readMetadataBoundsOfSuperclass(superclass);
},
[&](MetadataRef metadata) -> llvm::Optional<ClassMetadataBounds> {
auto cls = dyn_cast<TargetClassMetadata<Runtime>>(metadata);
if (!cls)
return llvm::None;
return cls->getClassBoundsAsSwiftSuperclass();
});
}
template <class Result, class DescriptorFn, class MetadataFn>
llvm::Optional<Result>
forTypeReference(TypeMetadataRecordKind refKind, StoredPointer ref,
const DescriptorFn &descriptorFn,
const MetadataFn &metadataFn) {
switch (refKind) {
case TypeMetadataRecordKind::IndirectNominalTypeDescriptor: {
StoredPointer descriptorAddress = 0;
if (!Reader->readInteger(RemoteAddress(ref), &descriptorAddress))
return llvm::None;
ref = descriptorAddress;
LLVM_FALLTHROUGH;
}
case TypeMetadataRecordKind::DirectNominalTypeDescriptor: {
auto descriptor = readContextDescriptor(ref);
if (!descriptor)
return llvm::None;
return descriptorFn(descriptor);
}
case TypeMetadataRecordKind::IndirectObjCClass: {
StoredPointer classRef = 0;
if (!Reader->readInteger(RemoteAddress(ref), &classRef))
return llvm::None;
auto metadata = readMetadata(classRef);
if (!metadata)
return llvm::None;
return metadataFn(metadata);
}
default:
return llvm::None;
}
}
/// Read a single generic type argument from a bound generic type /// Read a single generic type argument from a bound generic type
/// metadata. /// metadata.
llvm::Optional<StoredPointer> llvm::Optional<StoredPointer>
@@ -921,7 +983,7 @@ private:
if (descriptorAddress || !skipArtificialSubclasses) if (descriptorAddress || !skipArtificialSubclasses)
return static_cast<StoredPointer>(descriptorAddress); return static_cast<StoredPointer>(descriptorAddress);
auto superclassMetadataAddress = classMeta->SuperClass; auto superclassMetadataAddress = classMeta->Superclass;
if (!superclassMetadataAddress) if (!superclassMetadataAddress)
return 0; return 0;

File diff suppressed because it is too large Load Diff

View File

@@ -799,16 +799,11 @@ FUNCTION(GetGenericMetadata, swift_getGenericMetadata, C_CC,
ATTRS(NoUnwind, ReadOnly)) ATTRS(NoUnwind, ReadOnly))
// Metadata *swift_allocateGenericClassMetadata(ClassDescriptor *type, // Metadata *swift_allocateGenericClassMetadata(ClassDescriptor *type,
// const void *template,
// size_t templateSize,
// size_t templateAddressPoint,
// const void * const *arguments, // const void * const *arguments,
// objc_class *superclass, // const void *template);
// size_t numImmediateMembers);
FUNCTION(AllocateGenericClassMetadata, swift_allocateGenericClassMetadata, FUNCTION(AllocateGenericClassMetadata, swift_allocateGenericClassMetadata,
C_CC, RETURNS(TypeMetadataPtrTy), C_CC, RETURNS(TypeMetadataPtrTy),
ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, SizeTy, SizeTy, ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, Int8PtrPtrTy),
Int8PtrPtrTy, ObjCClassPtrTy, SizeTy),
ATTRS(NoUnwind)) ATTRS(NoUnwind))
// Metadata *swift_allocateGenericValueMetadata(ValueTypeDescriptor *type, // Metadata *swift_allocateGenericValueMetadata(ValueTypeDescriptor *type,

View File

@@ -113,8 +113,7 @@ private:
asImpl().noteStartOfImmediateMembers(theClass); asImpl().noteStartOfImmediateMembers(theClass);
// Add space for the generic parameters, if applicable. // Add space for the generic parameters, if applicable.
// Note that we only add references for the immediate parameters; // This must always be the first item in the immediate members.
// parameters for the parent context are handled by the parent.
asImpl().addGenericFields(theClass, type, theClass); asImpl().addGenericFields(theClass, type, theClass);
// Add vtable entries. // Add vtable entries.

View File

@@ -50,12 +50,10 @@ public:
// EnumMetadata header. // EnumMetadata header.
asImpl().addNominalTypeDescriptor(); asImpl().addNominalTypeDescriptor();
// If changing this layout, you must update the magic number in
// emitParentMetadataRef.
// Instantiation-specific. // Instantiation-specific.
// Add fields for generic cases. // Generic arguments.
// This must always be the first piece of trailing data.
asImpl().addGenericFields(Target, Target->getDeclaredTypeInContext()); asImpl().addGenericFields(Target, Target->getDeclaredTypeInContext());
// Reserve a word to cache the payload size if the type has dynamic layout. // Reserve a word to cache the payload size if the type has dynamic layout.

View File

@@ -3342,11 +3342,18 @@ IRGenModule::getAddrOfTypeMetadataPattern(NominalTypeDecl *D,
/// Returns the address of a class metadata base offset. /// Returns the address of a class metadata base offset.
llvm::Constant * llvm::Constant *
IRGenModule::getAddrOfClassMetadataBaseOffset(ClassDecl *D, IRGenModule::getAddrOfClassMetadataBounds(ClassDecl *D,
ForDefinition_t forDefinition) { ForDefinition_t forDefinition) {
// StoredClassMetadataBounds
auto layoutTy = llvm::StructType::get(getLLVMContext(), {
SizeTy, // Immediate members offset
Int32Ty, // Negative size in words
Int32Ty // Positive size in words
});
LinkEntity entity = LinkEntity::forClassMetadataBaseOffset(D); LinkEntity entity = LinkEntity::forClassMetadataBaseOffset(D);
return getAddrOfLLVMVariable(entity, getPointerAlignment(), forDefinition, return getAddrOfLLVMVariable(entity, getPointerAlignment(), forDefinition,
SizeTy, DebugTypeInfo()); layoutTy, DebugTypeInfo());
} }
/// Return the address of a generic type's metadata instantiation cache. /// Return the address of a generic type's metadata instantiation cache.

View File

@@ -1113,8 +1113,7 @@ static Address emitAddressOfSuperclassRefInClassMetadata(IRGenFunction &IGF,
unsigned index = 1; unsigned index = 1;
Address addr(metadata, IGF.IGM.getPointerAlignment()); Address addr(metadata, IGF.IGM.getPointerAlignment());
addr = IGF.Builder.CreateBitCast(addr, addr = IGF.Builder.CreateElementBitCast(addr, IGF.IGM.TypeMetadataPtrTy);
IGF.IGM.TypeMetadataPtrTy->getPointerTo());
return IGF.Builder.CreateConstArrayGEP(addr, index, IGF.IGM.getPointerSize()); return IGF.Builder.CreateConstArrayGEP(addr, index, IGF.IGM.getPointerSize());
} }
@@ -2644,19 +2643,12 @@ namespace {
/// Fill in the fields of a TypeGenericContextDescriptorHeader. /// Fill in the fields of a TypeGenericContextDescriptorHeader.
void addGenericParametersHeader() { void addGenericParametersHeader() {
asImpl().addGenericParamsOffset();
asImpl().addMetadataInstantiationFunction(); asImpl().addMetadataInstantiationFunction();
asImpl().addMetadataInstantiationCache(); asImpl().addMetadataInstantiationCache();
super::addGenericParametersHeader(); super::addGenericParametersHeader();
} }
void addGenericParamsOffset() {
// Include the offset to the generic argument vector inside a metadata
// record for this type.
B.addInt32(asImpl().getGenericParamsOffset() / IGM.getPointerSize());
}
void addMetadataInstantiationFunction() { void addMetadataInstantiationFunction() {
if (!HasMetadata) { if (!HasMetadata) {
B.addInt32(0); B.addInt32(0);
@@ -2716,7 +2708,6 @@ namespace {
} }
// Subclasses should provide: // Subclasses should provide:
// Size getGenericParamsOffset();
// ContextDescriptorKind getContextKind(); // ContextDescriptorKind getContextKind();
// void addLayoutInfo(); // ABI TODO: should be superseded // void addLayoutInfo(); // ABI TODO: should be superseded
}; };
@@ -2797,7 +2788,7 @@ namespace {
return cast<StructDecl>(Type); return cast<StructDecl>(Type);
} }
Size FieldVectorOffset, GenericParamsOffset; Size FieldVectorOffset;
public: public:
StructContextDescriptorBuilder(IRGenModule &IGM, StructDecl *Type, StructContextDescriptorBuilder(IRGenModule &IGM, StructDecl *Type,
@@ -2805,14 +2796,9 @@ namespace {
: super(IGM, Type, requireMetadata) : super(IGM, Type, requireMetadata)
{ {
auto &layout = IGM.getMetadataLayout(getType()); auto &layout = IGM.getMetadataLayout(getType());
GenericParamsOffset = layout.getStaticGenericRequirementsOffset();
FieldVectorOffset = layout.getFieldOffsetVectorOffset().getStatic(); FieldVectorOffset = layout.getFieldOffsetVectorOffset().getStatic();
} }
Size getGenericParamsOffset() {
return GenericParamsOffset;
}
ContextDescriptorKind getContextKind() { ContextDescriptorKind getContextKind() {
return ContextDescriptorKind::Struct; return ContextDescriptorKind::Struct;
} }
@@ -2848,7 +2834,6 @@ namespace {
return cast<EnumDecl>(Type); return cast<EnumDecl>(Type);
} }
Size GenericParamsOffset;
Size PayloadSizeOffset; Size PayloadSizeOffset;
const EnumImplStrategy &Strategy; const EnumImplStrategy &Strategy;
@@ -2860,15 +2845,10 @@ namespace {
getType()->getDeclaredTypeInContext()->getCanonicalType())) getType()->getDeclaredTypeInContext()->getCanonicalType()))
{ {
auto &layout = IGM.getMetadataLayout(getType()); auto &layout = IGM.getMetadataLayout(getType());
GenericParamsOffset = layout.getStaticGenericRequirementsOffset();
if (layout.hasPayloadSizeOffset()) if (layout.hasPayloadSizeOffset())
PayloadSizeOffset = layout.getPayloadSizeOffset().getStatic(); PayloadSizeOffset = layout.getPayloadSizeOffset().getStatic();
} }
Size getGenericParamsOffset() {
return GenericParamsOffset;
}
ContextDescriptorKind getContextKind() { ContextDescriptorKind getContextKind() {
return ContextDescriptorKind::Enum; return ContextDescriptorKind::Enum;
} }
@@ -2913,44 +2893,30 @@ namespace {
return cast<ClassDecl>(Type); return cast<ClassDecl>(Type);
} }
// Non-null unless the type is foreign.
ClassMetadataLayout *MetadataLayout = nullptr;
Optional<TypeEntityReference> SuperClassRef; Optional<TypeEntityReference> SuperClassRef;
// Offsets of key fields in the metadata records. SILVTable *VTable = nullptr;
Size FieldVectorOffset, GenericParamsOffset; unsigned VTableSize = 0;
SILVTable *VTable;
Size VTableOffset;
unsigned VTableSize;
public: public:
ClassContextDescriptorBuilder(IRGenModule &IGM, ClassDecl *Type, ClassContextDescriptorBuilder(IRGenModule &IGM, ClassDecl *Type,
RequireMetadata_t requireMetadata) RequireMetadata_t requireMetadata)
: super(IGM, Type, requireMetadata) : super(IGM, Type, requireMetadata)
{ {
if (getType()->isForeign()) { if (getType()->isForeign()) return;
VTable = nullptr;
VTableSize = 0; MetadataLayout = &IGM.getClassMetadataLayout(Type);
return;
}
if (auto superclassDecl = getType()->getSuperclassDecl()) { if (auto superclassDecl = getType()->getSuperclassDecl()) {
SuperClassRef = IGM.getTypeEntityReference(superclassDecl); SuperClassRef = IGM.getTypeEntityReference(superclassDecl);
} }
auto &layout = IGM.getClassMetadataLayout(getType()); VTableSize = MetadataLayout->getVTableSize();
if (VTableSize) {
VTable = IGM.getSILModule().lookUpVTable(getType()); VTable = IGM.getSILModule().lookUpVTable(getType());
VTableSize = layout.getVTableSize();
if (layout.hasResilientSuperclass()) {
FieldVectorOffset = layout.getRelativeFieldOffsetVectorOffset();
GenericParamsOffset = layout.getRelativeGenericRequirementsOffset();
VTableOffset = layout.getRelativeVTableOffset();
} else {
FieldVectorOffset = layout.getStaticFieldOffsetVectorOffset();
GenericParamsOffset = layout.getStaticGenericRequirementsOffset();
VTableOffset = layout.getStaticVTableOffset();
} }
} }
@@ -2966,14 +2932,17 @@ namespace {
uint16_t getKindSpecificFlags() { uint16_t getKindSpecificFlags() {
TypeContextDescriptorFlags flags; TypeContextDescriptorFlags flags;
flags.setIsReflectable(true); // class is always reflectable // Classes are always reflectable.
flags.setIsReflectable(true);
if (!getType()->isForeign()) { if (!getType()->isForeign()) {
if (MetadataLayout->areImmediateMembersNegative())
flags.class_setAreImmediateMembersNegative(true);
if (VTableSize != 0) if (VTableSize != 0)
flags.class_setHasVTable(true); flags.class_setHasVTable(true);
auto &layout = IGM.getClassMetadataLayout(getType()); if (MetadataLayout->hasResilientSuperclass())
if (layout.hasResilientSuperclass())
flags.class_setHasResilientSuperclass(true); flags.class_setHasResilientSuperclass(true);
} }
@@ -2986,15 +2955,21 @@ namespace {
return flags.getOpaqueValue(); return flags.getOpaqueValue();
} }
Size getGenericParamsOffset() { Size getFieldVectorOffset() {
return GenericParamsOffset; if (!MetadataLayout) return Size(0);
return (MetadataLayout->hasResilientSuperclass()
? MetadataLayout->getRelativeFieldOffsetVectorOffset()
: MetadataLayout->getStaticFieldOffsetVectorOffset());
} }
void addVTable() { void addVTable() {
if (VTableSize == 0) if (VTableSize == 0)
return; return;
B.addInt32(VTableOffset / IGM.getPointerSize()); auto offset = MetadataLayout->hasResilientSuperclass()
? MetadataLayout->getRelativeVTableOffset()
: MetadataLayout->getStaticVTableOffset();
B.addInt32(offset / IGM.getPointerSize());
B.addInt32(VTableSize); B.addInt32(VTableSize);
addVTableEntries(getType()); addVTableEntries(getType());
@@ -3052,11 +3027,45 @@ namespace {
B.addInt32(0); B.addInt32(0);
} }
// union {
// uint32_t MetadataNegativeSizeInWords;
// RelativeDirectPointer<StoredClassMetadataBounds>
// ResilientMetadataBounds;
// };
if (!MetadataLayout) {
// FIXME: do something meaningful for foreign classes?
B.addInt32(0);
} else if (!MetadataLayout->hasResilientSuperclass()) {
B.addInt32(MetadataLayout->getSize().AddressPoint
/ IGM.getPointerSize());
} else {
B.addRelativeAddress(
IGM.getAddrOfClassMetadataBounds(getType(), NotForDefinition));
}
// union {
// uint32_t MetadataPositiveSizeInWords;
// };
if (!MetadataLayout) {
// FIXME: do something meaningful for foreign classes?
B.addInt32(0);
} else if (!MetadataLayout->hasResilientSuperclass()) {
B.addInt32(MetadataLayout->getSize().getOffsetToEnd()
/ IGM.getPointerSize());
} else {
B.addInt32(0); // currently unused
}
// uint32_t NumImmediateMembers;
auto numImmediateMembers =
(MetadataLayout ? MetadataLayout->getNumImmediateMembers() : 0);
B.addInt32(numImmediateMembers);
// uint32_t NumFields; // uint32_t NumFields;
B.addInt32(std::distance(properties.begin(), properties.end())); B.addInt32(std::distance(properties.begin(), properties.end()));
// uint32_t FieldOffsetVectorOffset; // uint32_t FieldOffsetVectorOffset;
B.addInt32(FieldVectorOffset / IGM.getPointerSize()); B.addInt32(getFieldVectorOffset() / IGM.getPointerSize());
addFieldTypes(IGM, getType(), properties); addFieldTypes(IGM, getType(), properties);
} }
@@ -3193,7 +3202,11 @@ void IRGenModule::addFieldTypes(ArrayRef<CanType> fieldTypes) {
namespace { namespace {
/// An adapter class which turns a metadata layout class into a /// An adapter class which turns a metadata layout class into a
/// generic metadata layout class. /// generic metadata layout class.
template <class Impl, class Base> ///
/// If AddGenericArguments is false, fill ops will be added for the
/// arguments, but space for them won't actually be built into the
/// pattern.
template <class Impl, class Base, bool AddGenericArguments = true>
class GenericMetadataBuilderBase : public Base { class GenericMetadataBuilderBase : public Base {
typedef Base super; typedef Base super;
@@ -3319,6 +3332,10 @@ namespace {
TemplateSize = getNextOffsetFromTemplateHeader(); TemplateSize = getNextOffsetFromTemplateHeader();
asImpl().emitInstantiationDefinitions();
}
void emitInstantiationDefinitions() {
asImpl().emitCreateFunction(); asImpl().emitCreateFunction();
asImpl().emitInstantiationCache(); asImpl().emitInstantiationCache();
} }
@@ -3337,6 +3354,7 @@ namespace {
template <class... T> template <class... T>
void addGenericArgument(CanType type, T &&...args) { void addGenericArgument(CanType type, T &&...args) {
FillOps.push_back({type, None}); FillOps.push_back({type, None});
if (AddGenericArguments)
super::addGenericArgument(type, std::forward<T>(args)...); super::addGenericArgument(type, std::forward<T>(args)...);
} }
@@ -3344,6 +3362,7 @@ namespace {
void addGenericWitnessTable(CanType type, ProtocolConformanceRef conf, void addGenericWitnessTable(CanType type, ProtocolConformanceRef conf,
T &&...args) { T &&...args) {
FillOps.push_back({type, conf}); FillOps.push_back({type, conf});
if (AddGenericArguments)
super::addGenericWitnessTable(type, conf, std::forward<T>(args)...); super::addGenericWitnessTable(type, conf, std::forward<T>(args)...);
} }
@@ -3544,11 +3563,10 @@ namespace {
using super::Target; using super::Target;
using super::asImpl; using super::asImpl;
bool HasResilientSuperclass = false;
ConstantStructBuilder &B; ConstantStructBuilder &B;
const StructLayout &Layout; const StructLayout &Layout;
const ClassLayout &FieldLayout; const ClassLayout &FieldLayout;
ClassMetadataLayout &MetadataLayout;
MemberBuilder Members; MemberBuilder Members;
@@ -3558,31 +3576,35 @@ namespace {
const ClassLayout &fieldLayout) const ClassLayout &fieldLayout)
: super(IGM, theClass), B(builder), : super(IGM, theClass), B(builder),
Layout(layout), FieldLayout(fieldLayout), Layout(layout), FieldLayout(fieldLayout),
MetadataLayout(IGM.getClassMetadataLayout(theClass)),
Members(IGM, theClass, builder, layout, fieldLayout) {} Members(IGM, theClass, builder, layout, fieldLayout) {}
public: public:
void noteResilientSuperclass() { void noteResilientSuperclass() {}
HasResilientSuperclass = true;
}
void noteStartOfImmediateMembers(ClassDecl *theClass) { void noteStartOfImmediateMembers(ClassDecl *theClass) {
if (theClass == Target) {
emitClassMetadataBaseOffset();
}
}
/// Emit the base-offset variable for the class.
void emitClassMetadataBaseOffset() {
// Only classes defined in resilient modules, or those that have // Only classes defined in resilient modules, or those that have
// a resilient superclass need this. // a resilient superclass need this.
if (!HasResilientSuperclass && if (!MetadataLayout.hasResilientSuperclass() &&
!IGM.isResilient(theClass, ResilienceExpansion::Minimal)) { !IGM.isResilient(Target, ResilienceExpansion::Minimal)) {
return; return;
} }
if (theClass == Target) {
auto *offsetAddr = auto *offsetAddr =
IGM.getAddrOfClassMetadataBaseOffset(theClass, IGM.getAddrOfClassMetadataBounds(Target, ForDefinition);
ForDefinition);
auto *offsetVar = cast<llvm::GlobalVariable>(offsetAddr); auto *offsetVar = cast<llvm::GlobalVariable>(offsetAddr);
if (HasResilientSuperclass) { if (MetadataLayout.hasResilientSuperclass()) {
// If the superclass is resilient to us, we have to compute and // If the superclass is resilient to us, we have to compute and
// initialize the global when we initialize the metadata. // initialize the global when we initialize the metadata.
auto *init = llvm::ConstantInt::get(IGM.SizeTy, 0); auto init = llvm::ConstantAggregateZero::get(offsetVar->getValueType());
offsetVar->setInitializer(init); offsetVar->setInitializer(init);
offsetVar->setConstant(false); offsetVar->setConstant(false);
@@ -3591,15 +3613,23 @@ namespace {
// Otherwise, we know the offset at compile time, even if our // Otherwise, we know the offset at compile time, even if our
// clients do not, so just emit a constant. // clients do not, so just emit a constant.
auto &layout = IGM.getClassMetadataLayout(theClass); auto &layout = IGM.getClassMetadataLayout(Target);
auto value = layout.getStartOfImmediateMembers(); auto immediateMembersOffset = layout.getStartOfImmediateMembers();
auto *init = llvm::ConstantInt::get(IGM.SizeTy, value.getValue()); auto size = layout.getSize();
auto negativeSizeInWords = size.AddressPoint / IGM.getPointerSize();
auto positiveSizeInWords = size.getOffsetToEnd() / IGM.getPointerSize();
auto initTy = cast<llvm::StructType>(offsetVar->getValueType());
auto *init = llvm::ConstantStruct::get(initTy, {
llvm::ConstantInt::get(IGM.SizeTy, immediateMembersOffset.getValue()),
llvm::ConstantInt::get(IGM.Int32Ty, negativeSizeInWords),
llvm::ConstantInt::get(IGM.Int32Ty, positiveSizeInWords)
});
offsetVar->setInitializer(init); offsetVar->setInitializer(init);
offsetVar->setConstant(true); offsetVar->setConstant(true);
} }
}
/// The 'metadata flags' field in a class is actually a pointer to /// The 'metadata flags' field in a class is actually a pointer to
/// the metaclass object for the class. /// the metaclass object for the class.
@@ -3744,13 +3774,13 @@ namespace {
} }
void addClassSize() { void addClassSize() {
auto size = IGM.getMetadataLayout(Target).getSize(); auto size = MetadataLayout.getSize();
B.addInt32(size.FullSize.getValue()); B.addInt32(size.FullSize.getValue());
} }
void addClassAddressPoint() { void addClassAddressPoint() {
// FIXME: Wrong // FIXME: Wrong
auto size = IGM.getMetadataLayout(Target).getSize(); auto size = MetadataLayout.getSize();
B.addInt32(size.AddressPoint.getValue()); B.addInt32(size.AddressPoint.getValue());
} }
@@ -3857,52 +3887,20 @@ namespace {
return metadata; return metadata;
} }
// Store the runtime-computed metadata size of our superclass into the /// Materialize type metadata for the given type and store it into the
// target class's metadata base offset global variable. /// superclass field of the given metadata.
// void emitStoreOfSuperclass(IRGenFunction &IGF, CanType superclassType,
// Note that this code will run for each generic instantiation of the llvm::Value *metadata) {
// class, if the class is generic. This should be OK because the llvm::Value *superMetadata =
// metadata size does not change between generic instantiations, so emitClassHeapMetadataRef(IGF, superclassType,
// all stores after the first should be idempotent. MetadataValueType::TypeMetadata,
void emitInitializeClassMetadataBaseOffset(IRGenFunction &IGF, /*allowUninit*/ false);
llvm::Value *superMetadata) {
if (!HasResilientSuperclass)
return;
auto &layout = IGM.getClassMetadataLayout(Target); Address superField =
emitAddressOfSuperclassRefInClassMetadata(IGF, metadata);
// Load the size of the superclass metadata. superField = IGF.Builder.CreateElementBitCast(superField,
Address metadataAsBytes( IGM.TypeMetadataPtrTy);
IGF.Builder.CreateBitCast(superMetadata, IGF.IGM.Int8PtrTy), IGF.Builder.CreateStore(superMetadata, superField);
IGM.getPointerAlignment());
Address sizeSlot = IGF.Builder.CreateConstByteArrayGEP(
metadataAsBytes,
layout.getMetadataSizeOffset());
sizeSlot = IGF.Builder.CreateBitCast(sizeSlot,
IGM.Int32Ty->getPointerTo());
llvm::Value *size = IGF.Builder.CreateLoad(sizeSlot);
Address addressPointSlot = IGF.Builder.CreateConstByteArrayGEP(
metadataAsBytes,
layout.getMetadataAddressPointOffset());
addressPointSlot = IGF.Builder.CreateBitCast(addressPointSlot,
IGM.Int32Ty->getPointerTo());
llvm::Value *addressPoint = IGF.Builder.CreateLoad(addressPointSlot);
size = IGF.Builder.CreateSub(size, addressPoint);
if (IGM.SizeTy != IGM.Int32Ty)
size = IGF.Builder.CreateZExt(size, IGM.SizeTy);
Address offsetAddr(
IGM.getAddrOfClassMetadataBaseOffset(Target,
NotForDefinition),
IGM.getPointerAlignment());
// FIXME: Do we need to worry about memory barriers here, and when we
// load from the global?
IGF.Builder.CreateStore(size, offsetAddr);
} }
// Update vtable entries for method overrides. The runtime copies in // Update vtable entries for method overrides. The runtime copies in
@@ -3989,7 +3987,6 @@ namespace {
using super::Target; using super::Target;
using super::B; using super::B;
using super::addReferenceToHeapMetadata; using super::addReferenceToHeapMetadata;
using super::emitInitializeClassMetadataBaseOffset;
using super::emitFinishInitializationOfClassMetadata; using super::emitFinishInitializationOfClassMetadata;
using super::emitFinishIdempotentInitialization; using super::emitFinishIdempotentInitialization;
using super::emitFieldOffsetGlobals; using super::emitFieldOffsetGlobals;
@@ -4080,18 +4077,7 @@ namespace {
// Initialize the superclass if we didn't do so as a constant. // Initialize the superclass if we didn't do so as a constant.
if (HasUnfilledSuperclass) { if (HasUnfilledSuperclass) {
auto superclass = type->getSuperclass()->getCanonicalType(); auto superclass = type->getSuperclass()->getCanonicalType();
llvm::Value *superMetadata = this->emitStoreOfSuperclass(IGF, superclass, metadata);
emitClassHeapMetadataRef(IGF, superclass,
MetadataValueType::TypeMetadata,
/*allowUninit*/ false);
emitInitializeClassMetadataBaseOffset(IGF, superMetadata);
Address superField =
emitAddressOfSuperclassRefInClassMetadata(IGF, metadata);
superField = IGF.Builder.CreateElementBitCast(superField,
IGM.TypeMetadataPtrTy);
IGF.Builder.CreateStore(superMetadata, superField);
} }
// Relocate the metadata if it has a superclass that is resilient // Relocate the metadata if it has a superclass that is resilient
@@ -4139,20 +4125,18 @@ namespace {
: super(IGM, theClass, builder, layout, fieldLayout) {} : super(IGM, theClass, builder, layout, fieldLayout) {}
}; };
/// A builder for generic class metadata. /// A builder for GenericClassMetadataPattern objects.
class GenericClassMetadataBuilder : class GenericClassMetadataBuilder :
public GenericMetadataBuilderBase<GenericClassMetadataBuilder, public GenericMetadataBuilderBase<GenericClassMetadataBuilder,
ClassMetadataBuilderBase<GenericClassMetadataBuilder, ClassMetadataBuilderBase<GenericClassMetadataBuilder,
ResilientClassMemberBuilder>> ResilientClassMemberBuilder>,
/*add generic arguments*/ false>
{ {
typedef GenericMetadataBuilderBase super; typedef GenericMetadataBuilderBase super;
Size MetaclassPtrOffset = Size::invalid(); Optional<ConstantAggregateBuilderBase::PlaceholderPosition>
Size ClassRODataPtrOffset = Size::invalid(); NumExtraDataWords, ClassRODataOffset, MetaclassObjectOffset,
Size MetaclassRODataPtrOffset = Size::invalid(); MetaclassRODataOffset;
Size DependentMetaclassPoint = Size::invalid();
Size DependentClassRODataPoint = Size::invalid();
Size DependentMetaclassRODataPoint = Size::invalid();
public: public:
GenericClassMetadataBuilder(IRGenModule &IGM, ClassDecl *theClass, GenericClassMetadataBuilder(IRGenModule &IGM, ClassDecl *theClass,
ConstantStructBuilder &B, ConstantStructBuilder &B,
@@ -4165,70 +4149,107 @@ namespace {
HasDependentMetadata = true; HasDependentMetadata = true;
} }
void addSuperClass() { void layout() {
// Filled in by the runtime. // HeapObjectDestroyer *Destroy;
B.addNullPointer(IGM.TypeMetadataPtrTy); addDestructorFunction();
// ClassIVarDestroyer *IVarDestroyer;
addIVarDestroyer();
// ClassFlags Flags;
addClassFlags();
// TODO: consider using this to initialize the field offsets (and then
// suppress dynamic layout for them).
// uint16_t ImmediateMembersPattern_Size;
// uint16_t ImmediateMembersPattern_TargetOffset;
B.addInt16(0);
B.addInt16(0);
// uint16_t NumExtraDataWords;
NumExtraDataWords = B.addPlaceholderWithSize(IGM.Int16Ty);
// uint16_t ClassRODataOffset;
ClassRODataOffset = B.addPlaceholderWithSize(IGM.Int16Ty);
// uint16_t MetaclassObjectOffset;
MetaclassObjectOffset = B.addPlaceholderWithSize(IGM.Int16Ty);
// uint16_t MetadataRODataOffset;
MetaclassRODataOffset = B.addPlaceholderWithSize(IGM.Int16Ty);
// Immediate members pattern:
// (currently we don't take advantage of this)
// Extra data pattern:
addExtraDataPattern();
// We're done with the pattern now.
#ifndef NDEBUG
auto finalOffset = getNextOffsetFromTemplateHeader();
#endif
// Emit the base-offset variable.
emitClassMetadataBaseOffset();
// Emit the nominal type descriptor.
(void) ClassContextDescriptorBuilder(IGM, Target, RequireMetadata).emit();
// Register fill ops for all the immediate type arguments.
addGenericFields(Target, Target->getDeclaredTypeInContext(), Target);
// Emit instantiation information.
emitInstantiationDefinitions();
assert(finalOffset == getNextOffsetFromTemplateHeader() &&
"shouldn't have added anything to the pattern");
} }
llvm::Value *emitAllocateMetadata(IRGenFunction &IGF, uint16_t getOffsetInWords(Size begin, Size offset) {
llvm::Value *descriptor, // Subtract the offset from the initial offset and divide by the
llvm::Value *arguments) { // pointer size, rounding up.
llvm::Value *superMetadata; auto result =
if (Target->hasSuperclass()) { (offset - begin + IGM.getPointerSize() - Size(1))
Type superclass = Target->getSuperclass(); / IGM.getPointerSize();
superclass = Target->mapTypeIntoContext(superclass); assert(result < (1 << 16));
superMetadata = return uint16_t(result);
emitClassHeapMetadataRef(IGF, superclass->getCanonicalType(), };
MetadataValueType::ObjCClass);
emitInitializeClassMetadataBaseOffset(IGF, superMetadata); void addExtraDataPattern() {
} else if (IGM.ObjCInterop) { Size extraDataBegin = getNextOffsetFromTemplateHeader();
superMetadata = emitObjCHeapMetadataRef(IGF,
IGM.getObjCRuntimeBaseForSwiftRootClass(Target)); uint16_t classRODataOffsetWords = 0;
} else { uint16_t metaclassObjectOffsetWords = 0;
superMetadata = llvm::ConstantPointerNull::get(IGM.ObjCClassPtrTy); uint16_t metaclassRODataOffsetWords = 0;
if (IGM.ObjCInterop) {
// Add the metaclass object.
metaclassObjectOffsetWords =
getOffsetInWords(extraDataBegin, getNextOffsetFromTemplateHeader());
addMetaclassObject();
// Add the RO-data objects.
auto roDataPoints =
emitClassPrivateDataFields(IGM, B, Target);
classRODataOffsetWords =
getOffsetInWords(extraDataBegin, roDataPoints.first);
metaclassRODataOffsetWords =
getOffsetInWords(extraDataBegin, roDataPoints.second);
} }
auto templatePointer = IGM.getAddrOfTypeMetadataPattern(Target); auto extraDataEnd = getNextOffsetFromTemplateHeader();
auto templateSize = IGM.getSize(TemplateSize); auto numExtraDataWords = getOffsetInWords(extraDataBegin, extraDataEnd);
auto templateAddressPoint = IGM.getSize(AddressPoint);
auto numImmediateMembers = B.fillPlaceholderWithInt(*NumExtraDataWords, IGM.Int16Ty,
IGM.getSize(Size(IGM.getClassMetadataLayout(Target).getNumImmediateMembers())); numExtraDataWords);
B.fillPlaceholderWithInt(*ClassRODataOffset, IGM.Int16Ty,
return IGF.Builder.CreateCall(IGM.getAllocateGenericClassMetadataFn(), classRODataOffsetWords);
{descriptor, templatePointer, templateSize, B.fillPlaceholderWithInt(*MetaclassObjectOffset, IGM.Int16Ty,
templateAddressPoint, arguments, metaclassObjectOffsetWords);
superMetadata, numImmediateMembers}); B.fillPlaceholderWithInt(*MetaclassRODataOffset, IGM.Int16Ty,
metaclassRODataOffsetWords);
} }
void addMetadataFlags() { void addMetaclassObject() {
// The metaclass pointer will be instantiated here.
MetaclassPtrOffset = getNextOffsetFromTemplateHeader();
B.addInt(IGM.MetadataKindTy, 0);
}
void addClassDataPointer() {
// The rodata pointer will be instantiated here.
// Make sure we at least set the 'is Swift class' bit, though.
ClassRODataPtrOffset = getNextOffsetFromTemplateHeader();
if (!IGM.ObjCInterop) {
// FIXME: Remove null data altogether rdar://problem/18801263
B.addInt(IGM.MetadataKindTy, 1);
} else {
B.addInt(IGM.MetadataKindTy, IGM.UseDarwinPreStableABIBit ? 1 : 2);
}
}
void addDependentData() {
if (!IGM.ObjCInterop) {
// Every piece of data in the dependent data appears to be related to
// Objective-C information. If we're not doing Objective-C interop, we
// can just skip adding it to the class.
return;
}
// Emit space for the dependent metaclass.
DependentMetaclassPoint = getNextOffsetFromTemplateHeader();
// isa // isa
ClassDecl *rootClass = getRootClassForMetaclass(IGM, Target); ClassDecl *rootClass = getRootClassForMetaclass(IGM, Target);
auto isa = IGM.getAddrOfMetaclassObject(rootClass, NotForDefinition); auto isa = IGM.getAddrOfMetaclassObject(rootClass, NotForDefinition);
@@ -4240,17 +4261,9 @@ namespace {
// vtable // vtable
B.add(IGM.getObjCEmptyVTablePtr()); B.add(IGM.getObjCEmptyVTablePtr());
// rodata, which is always dependent // rodata, which is always dependent
MetaclassRODataPtrOffset = getNextOffsetFromTemplateHeader();
B.addInt(IGM.IntPtrTy, 0); B.addInt(IGM.IntPtrTy, 0);
std::tie(DependentClassRODataPoint, DependentMetaclassRODataPoint)
= emitClassPrivateDataFields(IGM, B, Target);
} }
void noteStartOfFieldOffsets(ClassDecl *whichClass) {}
void noteEndOfFieldOffsets(ClassDecl *whichClass) {}
// Suppress GenericMetadataBuilderBase's default behavior of introducing // Suppress GenericMetadataBuilderBase's default behavior of introducing
// fill ops for generic arguments unless they belong directly to the target // fill ops for generic arguments unless they belong directly to the target
// class and not its ancestors. // class and not its ancestors.
@@ -4278,91 +4291,29 @@ namespace {
} }
} }
llvm::Value *emitAllocateMetadata(IRGenFunction &IGF,
llvm::Value *descriptor,
llvm::Value *arguments) {
auto templatePointer = IGM.getAddrOfTypeMetadataPattern(Target);
auto metadata =
IGF.Builder.CreateCall(IGM.getAllocateGenericClassMetadataFn(),
{descriptor, arguments, templatePointer});
return metadata;
}
void emitInitializeMetadata(IRGenFunction &IGF, void emitInitializeMetadata(IRGenFunction &IGF,
llvm::Value *metadata, llvm::Value *metadata,
bool isVWTMutable) { bool isVWTMutable) {
assert(!HasDependentVWT && "class should never have dependent VWT"); assert(!HasDependentVWT && "class should never have dependent VWT");
// Fill in the metaclass pointer. // Install the superclass. The runtime takes care of installing
Address metadataPtr(IGF.Builder.CreateBitCast(metadata, IGF.IGM.Int8PtrPtrTy), // SwiftObject if we're building with ObjC interop and don't have
IGF.IGM.getPointerAlignment()); // a formal superclass.
if (Target->hasSuperclass()) {
llvm::Value *metaclass; CanType superclass = Target->mapTypeIntoContext(Target->getSuperclass())
if (IGF.IGM.ObjCInterop) { ->getCanonicalType();
assert(!DependentMetaclassPoint.isInvalid()); emitStoreOfSuperclass(IGF, superclass, metadata);
assert(!MetaclassPtrOffset.isInvalid());
Address metaclassPtrSlot = createPointerSizedGEP(IGF, metadataPtr,
MetaclassPtrOffset - AddressPoint);
metaclassPtrSlot = IGF.Builder.CreateBitCast(metaclassPtrSlot,
IGF.IGM.ObjCClassPtrTy->getPointerTo());
Address metaclassRawPtr = createPointerSizedGEP(IGF, metadataPtr,
DependentMetaclassPoint - AddressPoint);
metaclass = IGF.Builder.CreateBitCast(metaclassRawPtr,
IGF.IGM.ObjCClassPtrTy)
.getAddress();
IGF.Builder.CreateStore(metaclass, metaclassPtrSlot);
} else {
// FIXME: Remove altogether rather than injecting a NULL value.
// rdar://problem/18801263
assert(!MetaclassPtrOffset.isInvalid());
Address metaclassPtrSlot = createPointerSizedGEP(IGF, metadataPtr,
MetaclassPtrOffset - AddressPoint);
metaclassPtrSlot = IGF.Builder.CreateBitCast(metaclassPtrSlot,
IGF.IGM.ObjCClassPtrTy->getPointerTo());
IGF.Builder.CreateStore(
llvm::ConstantPointerNull::get(IGF.IGM.ObjCClassPtrTy),
metaclassPtrSlot);
}
// Fill in the rodata reference in the class.
Address classRODataPtr;
if (IGF.IGM.ObjCInterop) {
assert(!DependentClassRODataPoint.isInvalid());
assert(!ClassRODataPtrOffset.isInvalid());
Address rodataPtrSlot = createPointerSizedGEP(IGF, metadataPtr,
ClassRODataPtrOffset - AddressPoint);
rodataPtrSlot = IGF.Builder.CreateBitCast(rodataPtrSlot,
IGF.IGM.IntPtrTy->getPointerTo());
classRODataPtr = createPointerSizedGEP(IGF, metadataPtr,
DependentClassRODataPoint - AddressPoint);
// Set the low bit of the value to indicate "compiled by Swift".
llvm::Value *rodata = IGF.Builder.CreatePtrToInt(
classRODataPtr.getAddress(), IGF.IGM.IntPtrTy);
rodata = IGF.Builder.CreateOr(rodata, 1);
IGF.Builder.CreateStore(rodata, rodataPtrSlot);
} else {
// NOTE: Unlike other bits of the metadata that should later be removed,
// this one is important because things check this value's flags to
// determine what kind of object it is. That said, if those checks
// are determined to be removable, we can remove this as well per
// rdar://problem/18801263
assert(!ClassRODataPtrOffset.isInvalid());
Address rodataPtrSlot = createPointerSizedGEP(IGF, metadataPtr,
ClassRODataPtrOffset - AddressPoint);
rodataPtrSlot = IGF.Builder.CreateBitCast(rodataPtrSlot,
IGF.IGM.IntPtrTy->getPointerTo());
IGF.Builder.CreateStore(llvm::ConstantInt::get(IGF.IGM.IntPtrTy, 1),
rodataPtrSlot);
}
// Fill in the rodata reference in the metaclass.
Address metaclassRODataPtr;
if (IGF.IGM.ObjCInterop) {
assert(!DependentMetaclassRODataPoint.isInvalid());
assert(!MetaclassRODataPtrOffset.isInvalid());
Address rodataPtrSlot = createPointerSizedGEP(IGF, metadataPtr,
MetaclassRODataPtrOffset - AddressPoint);
rodataPtrSlot = IGF.Builder.CreateBitCast(rodataPtrSlot,
IGF.IGM.IntPtrTy->getPointerTo());
metaclassRODataPtr = createPointerSizedGEP(IGF, metadataPtr,
DependentMetaclassRODataPoint - AddressPoint);
llvm::Value *rodata = IGF.Builder.CreatePtrToInt(
metaclassRODataPtr.getAddress(), IGF.IGM.IntPtrTy);
IGF.Builder.CreateStore(rodata, rodataPtrSlot);
} }
// We can assume that this never relocates the metadata because // We can assume that this never relocates the metadata because

View File

@@ -150,13 +150,6 @@ namespace irgen {
NominalTypeDecl *decl, NominalTypeDecl *decl,
ArchetypeType *archetype); ArchetypeType *archetype);
/// Given a reference to nominal type metadata of the given type,
/// derive a reference to the parent type metadata. There must be a
/// parent type.
llvm::Value *emitParentMetadataRef(IRGenFunction &IGF,
NominalTypeDecl *theDecl,
llvm::Value *metadata);
/// Given a reference to nominal type metadata of the given type, /// Given a reference to nominal type metadata of the given type,
/// derive a reference to the type metadata stored in the nth /// derive a reference to the type metadata stored in the nth
/// requirement slot. The type must have generic arguments. /// requirement slot. The type must have generic arguments.

View File

@@ -1150,7 +1150,7 @@ public:
/// Determine whether the given type requires foreign type metadata. /// Determine whether the given type requires foreign type metadata.
bool requiresForeignTypeMetadata(CanType type); bool requiresForeignTypeMetadata(CanType type);
llvm::Constant *getAddrOfClassMetadataBaseOffset(ClassDecl *D, llvm::Constant *getAddrOfClassMetadataBounds(ClassDecl *D,
ForDefinition_t forDefinition); ForDefinition_t forDefinition);
llvm::Constant *getAddrOfTypeContextDescriptor(NominalTypeDecl *D, llvm::Constant *getAddrOfTypeContextDescriptor(NominalTypeDecl *D,
RequireMetadata_t requireMetadata, RequireMetadata_t requireMetadata,

View File

@@ -162,11 +162,13 @@ Offset NominalMetadataLayout::emitOffset(IRGenFunction &IGF,
if (offset.isStatic()) if (offset.isStatic())
return Offset(offset.getStaticOffset()); return Offset(offset.getStaticOffset());
Address offsetBaseAddr( Address layoutAddr(
IGF.IGM.getAddrOfClassMetadataBaseOffset(cast<ClassDecl>(getDecl()), IGF.IGM.getAddrOfClassMetadataBounds(cast<ClassDecl>(getDecl()),
NotForDefinition), NotForDefinition),
IGF.IGM.getPointerAlignment()); IGF.IGM.getPointerAlignment());
auto offsetBaseAddr = IGF.Builder.CreateStructGEP(layoutAddr, 0, Size(0));
// FIXME: Should this be an invariant load? // FIXME: Should this be an invariant load?
llvm::Value *offsetVal = IGF.Builder.CreateLoad(offsetBaseAddr, "base"); llvm::Value *offsetVal = IGF.Builder.CreateLoad(offsetBaseAddr, "base");

View File

@@ -227,6 +227,10 @@ public:
return HasResilientSuperclass; return HasResilientSuperclass;
} }
constexpr static bool areImmediateMembersNegative() {
return false;
}
Size getMetadataSizeOffset() const; Size getMetadataSizeOffset() const;
Size getMetadataAddressPointOffset() const; Size getMetadataAddressPointOffset() const;

View File

@@ -48,10 +48,10 @@ public:
// StructMetadata header. // StructMetadata header.
asImpl().addNominalTypeDescriptor(); asImpl().addNominalTypeDescriptor();
// If changing this layout, you must update the magic number in
// emitParentMetadataRef.
// Instantiation-specific. // Instantiation-specific.
// Generic arguments.
// This must always be the first piece of trailing data.
asImpl().addGenericFields(Target, Target->getDeclaredTypeInContext()); asImpl().addGenericFields(Target, Target->getDeclaredTypeInContext());
// Struct field offsets. // Struct field offsets.

View File

@@ -75,7 +75,7 @@ static void _buildNameForMetadata(const Metadata *type,
auto classType = static_cast<const ClassMetadata *>(type); auto classType = static_cast<const ClassMetadata *>(type);
// Look through artificial subclasses. // Look through artificial subclasses.
while (classType->isTypeMetadata() && classType->isArtificialSubclass()) while (classType->isTypeMetadata() && classType->isArtificialSubclass())
classType = classType->SuperClass; classType = classType->Superclass;
// Ask the Objective-C runtime to name ObjC classes. // Ask the Objective-C runtime to name ObjC classes.
if (!classType->isTypeMetadata()) { if (!classType->isTypeMetadata()) {
@@ -262,7 +262,7 @@ _dynamicCastClassMetatype(const ClassMetadata *sourceType,
if (sourceType == targetType) { if (sourceType == targetType) {
return sourceType; return sourceType;
} }
sourceType = sourceType->SuperClass; sourceType = sourceType->Superclass;
} while (sourceType); } while (sourceType);
return nullptr; return nullptr;
@@ -3228,7 +3228,7 @@ SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
const Metadata *swift::_swift_class_getSuperclass(const Metadata *theClass) { const Metadata *swift::_swift_class_getSuperclass(const Metadata *theClass) {
if (const ClassMetadata *classType = theClass->getClassObject()) if (const ClassMetadata *classType = theClass->getClassObject())
if (classHasSuperclass(classType)) if (classHasSuperclass(classType))
return getMetadataForClass(classType->SuperClass); return getMetadataForClass(classType->Superclass);
return nullptr; return nullptr;
} }

View File

@@ -263,7 +263,7 @@ _buildDemanglingForNominalType(const Metadata *type, Demangle::Demangler &Dem) {
#if SWIFT_OBJC_INTEROP #if SWIFT_OBJC_INTEROP
// Peek through artificial subclasses. // Peek through artificial subclasses.
while (classType->isTypeMetadata() && classType->isArtificialSubclass()) while (classType->isTypeMetadata() && classType->isArtificialSubclass())
classType = classType->SuperClass; classType = classType->Superclass;
#endif #endif
description = classType->getDescription(); description = classType->getDescription();
break; break;

View File

@@ -61,7 +61,7 @@ static SWIFT_CC(swift) void _destroyErrorObject(SWIFT_CONTEXT HeapObject *obj) {
/// Heap metadata for Error boxes. /// Heap metadata for Error boxes.
static const FullMetadata<HeapMetadata> ErrorMetadata{ static const FullMetadata<HeapMetadata> ErrorMetadata{
HeapMetadataHeader{{_destroyErrorObject}, {&VALUE_WITNESS_SYM(Bo)}}, HeapMetadataHeader{{_destroyErrorObject}, {&VALUE_WITNESS_SYM(Bo)}},
Metadata{MetadataKind::ErrorObject}, HeapMetadata(MetadataKind::ErrorObject),
}; };
BoxPair BoxPair

View File

@@ -658,10 +658,10 @@ void swift::swift_deallocPartialClassInstance(HeapObject *object,
} }
#endif #endif
if (auto fn = classMetadata->getIVarDestroyer()) if (classMetadata->IVarDestroyer)
fn(object); classMetadata->IVarDestroyer(object);
classMetadata = classMetadata->SuperClass->getClassObject(); classMetadata = classMetadata->Superclass->getClassObject();
assert(classMetadata && "Given metatype not a superclass of object type?"); assert(classMetadata && "Given metatype not a superclass of object type?");
} }
@@ -671,7 +671,7 @@ void swift::swift_deallocPartialClassInstance(HeapObject *object,
if (!usesNativeSwiftReferenceCounting(classMetadata)) { if (!usesNativeSwiftReferenceCounting(classMetadata)) {
// Find the pure Objective-C superclass. // Find the pure Objective-C superclass.
while (!classMetadata->isPureObjC()) while (!classMetadata->isPureObjC())
classMetadata = classMetadata->SuperClass->getClassObject(); classMetadata = classMetadata->Superclass->getClassObject();
// Set the class to the pure Objective-C superclass, so that when dealloc // Set the class to the pure Objective-C superclass, so that when dealloc
// runs, it starts at that superclass. // runs, it starts at that superclass.

View File

@@ -74,6 +74,92 @@ static int compareIntegers(T left, T right) {
static const size_t ValueTypeMetadataAddressPoint = sizeof(TypeMetadataHeader); static const size_t ValueTypeMetadataAddressPoint = sizeof(TypeMetadataHeader);
static ClassMetadataBounds
computeMetadataBoundsForSuperclass(const void *ref,
TypeMetadataRecordKind refKind) {
switch (refKind) {
case TypeMetadataRecordKind::IndirectNominalTypeDescriptor: {
auto description = *reinterpret_cast<const ClassDescriptor * const *>(ref);
if (!description) {
swift::fatalError(0, "instantiating class metadata for class with "
"missing weak-linked ancestor");
}
return description->getMetadataBounds();
}
case TypeMetadataRecordKind::DirectNominalTypeDescriptor: {
auto description = reinterpret_cast<const ClassDescriptor *>(ref);
return description->getMetadataBounds();
}
case TypeMetadataRecordKind::IndirectObjCClass:
#if SWIFT_OBJC_INTEROP
{
auto cls = *reinterpret_cast<const Class *>(ref);
cls = swift_getInitializedObjCClass(cls);
auto metadata = reinterpret_cast<const ClassMetadata *>(cls);
return metadata->getClassBoundsAsSwiftSuperclass();
}
#else
// fallthrough
#endif
case TypeMetadataRecordKind::Reserved:
break;
}
swift_runtime_unreachable("unsupported superclass reference kind");
}
static ClassMetadataBounds computeMetadataBoundsFromSuperclass(
const ClassDescriptor *description,
StoredClassMetadataBounds &storedBounds) {
ClassMetadataBounds bounds;
// Compute the bounds for the superclass, extending it to the minimum
// bounds of a Swift class.
if (const void *superRef = description->Superclass.get()) {
bounds = computeMetadataBoundsForSuperclass(superRef,
description->getSuperclassReferenceKind());
} else {
bounds = ClassMetadataBounds::forSwiftRootClass();
}
// Add the subclass's immediate members.
bounds.adjustForSubclass(description->areImmediateMembersNegative(),
description->NumImmediateMembers);
// Cache before returning.
storedBounds.initialize(bounds);
return bounds;
}
ClassMetadataBounds
swift::getResilientMetadataBounds(const ClassDescriptor *description) {
assert(description->hasResilientSuperclass());
auto &storedBounds = *description->ResilientMetadataBounds.get();
ClassMetadataBounds bounds;
if (storedBounds.tryGet(bounds)) {
return bounds;
}
return computeMetadataBoundsFromSuperclass(description, storedBounds);
}
int32_t
swift::getResilientImmediateMembersOffset(const ClassDescriptor *description) {
assert(description->hasResilientSuperclass());
auto &storedBounds = *description->ResilientMetadataBounds.get();
ptrdiff_t result;
if (storedBounds.tryGetImmediateMembersOffset(result)) {
return result / sizeof(void*);
}
auto bounds = computeMetadataBoundsFromSuperclass(description, storedBounds);
return bounds.ImmediateMembersOffset / sizeof(void*);
}
namespace { namespace {
struct GenericCacheEntry; struct GenericCacheEntry;
@@ -94,9 +180,7 @@ namespace {
size_t getNumArguments() const { return NumArguments; } size_t getNumArguments() const { return NumArguments; }
static GenericCacheEntry *getFromMetadata( static GenericCacheEntry *getFromMetadata(Metadata *metadata) {
const TypeGenericContextDescriptorHeader &generics,
Metadata *metadata) {
char *bytes = (char*) metadata; char *bytes = (char*) metadata;
if (auto classType = dyn_cast<ClassMetadata>(metadata)) { if (auto classType = dyn_cast<ClassMetadata>(metadata)) {
assert(classType->isTypeMetadata()); assert(classType->isTypeMetadata());
@@ -142,65 +226,148 @@ static GenericMetadataCache &unsafeGetInitializedCache(
return lazyCache->unsafeGetAlreadyInitialized(); return lazyCache->unsafeGetAlreadyInitialized();
} }
#ifndef NDEBUG
extern "C" void *_objc_empty_cache;
#endif
static void
initializeClassMetadataFromPattern(ClassMetadata *metadata,
ClassMetadataBounds bounds,
const ClassDescriptor *description,
const GenericClassMetadataPattern *pattern) {
auto fullMetadata = asFullMetadata(metadata);
char *rawMetadata = reinterpret_cast<char*>(metadata);
// Install the extra-data pattern.
void **metadataExtraData =
reinterpret_cast<void**>(rawMetadata) + bounds.PositiveSizeInWords;
memcpy(metadataExtraData, pattern->getExtraDataPattern(),
size_t(pattern->NumExtraDataWords) * sizeof(void*));
// Install the immediate members pattern:
void **immediateMembers =
reinterpret_cast<void**>(rawMetadata + bounds.ImmediateMembersOffset);
// Zero out the entire immediate-members section.
// TODO: only memset the parts that aren't covered by the pattern.
memset(immediateMembers, 0, description->getImmediateMembersSize());
// Copy the immediate-members pattern.
if (auto immediateSize = pattern->ImmediateMembersPattern_Size) {
memcpy(immediateMembers + pattern->ImmediateMembersPattern_TargetOffset,
pattern->getImmediateMembersPattern(),
size_t(immediateSize) * sizeof(void*));
}
// Initialize the header:
// Heap destructor.
fullMetadata->destroy = pattern->Destroy;
// Value witness table.
#if SWIFT_OBJC_INTEROP
fullMetadata->ValueWitnesses =
(pattern->Flags & ClassFlags::UsesSwiftRefcounting)
? &VALUE_WITNESS_SYM(Bo)
: &VALUE_WITNESS_SYM(BO);
#else
fullMetadata->ValueWitnesses = &VALUE_WITNESS_SYM(Bo);
#endif
#if SWIFT_OBJC_INTEROP
// Install the metaclass's RO-data pointer.
auto metaclass = reinterpret_cast<AnyClassMetadata *>(
metadataExtraData + pattern->MetaclassObjectOffset);
auto metaclassRO = metadataExtraData + pattern->MetaclassRODataOffset;
metaclass->Data = reinterpret_cast<uintptr_t>(metaclassRO);
#endif
// MetadataKind / isa.
#if SWIFT_OBJC_INTEROP
metadata->setClassISA(metaclass);
#else
metadata->setKind(MetadataKind::Class);
#endif
// Superclass.
metadata->Superclass = nullptr;
#if SWIFT_OBJC_INTEROP
// If the class doesn't have a formal superclass, automatically set
// it to SwiftObject.
if (!description->hasSuperclass()) {
metadata->Superclass = getRootSuperclass();
}
#endif
#if SWIFT_OBJC_INTEROP
// Cache data. Install the same initializer that the compiler is
// required to use. We don't need to do this in non-ObjC-interop modes.
metadata->CacheData[0] = &_objc_empty_cache;
metadata->CacheData[1] = nullptr;
#endif
// RO-data pointer.
#if SWIFT_OBJC_INTEROP
auto classRO = metadataExtraData + pattern->ClassRODataOffset;
metadata->Data =
reinterpret_cast<uintptr_t>(classRO) | SWIFT_CLASS_IS_SWIFT_MASK;
#else
metadata->Data = SWIFT_CLASS_IS_SWIFT_MASK;
#endif
// Class flags.
metadata->Flags = pattern->Flags;
// Instance layout.
metadata->InstanceAddressPoint = 0;
metadata->InstanceSize = 0;
metadata->InstanceAlignMask = 0;
// Reserved.
metadata->Reserved = 0;
// Class metadata layout.
metadata->ClassSize = bounds.getTotalSizeInBytes();
metadata->ClassAddressPoint = bounds.getAddressPointInBytes();
// Class descriptor.
metadata->setDescription(description);
// I-var destroyer.
metadata->IVarDestroyer = pattern->IVarDestroyer;
}
ClassMetadata * ClassMetadata *
swift::swift_allocateGenericClassMetadata(const ClassDescriptor *description, swift::swift_allocateGenericClassMetadata(const ClassDescriptor *description,
const void *metadataTemplate,
size_t templateSize,
size_t templateAddressPoint,
const void *arguments, const void *arguments,
ClassMetadata *superclass, const GenericClassMetadataPattern *pattern){
size_t numImmediateMembers) {
void * const *argumentsAsArray = reinterpret_cast<void * const *>(arguments); void * const *argumentsAsArray = reinterpret_cast<void * const *>(arguments);
auto &generics = description->getFullGenericContextHeader(); auto &generics = description->getFullGenericContextHeader();
auto &cache = unsafeGetInitializedCache(generics);
size_t numGenericArguments = generics.Base.NumKeyArguments; size_t numGenericArguments = generics.Base.NumKeyArguments;
size_t metadataSize; // Compute the formal bounds of the metadata.
if (superclass && superclass->isTypeMetadata()) { auto bounds = description->getMetadataBounds();
assert(superclass->getClassAddressPoint() <= templateAddressPoint);
metadataSize = (superclass->getClassSize() - // Augment that with any required extra data from the pattern.
superclass->getClassAddressPoint() + auto allocationBounds = bounds;
templateAddressPoint + allocationBounds.PositiveSizeInWords += pattern->NumExtraDataWords;
numImmediateMembers * sizeof(void *));
assert(templateSize <= metadataSize);
} else {
metadataSize = (templateSize +
numImmediateMembers * sizeof(void *));
}
auto &cache = unsafeGetInitializedCache(generics); auto entry = GenericCacheEntry::allocate(cache.getAllocator(),
char *bytes = GenericCacheEntry::allocate(cache.getAllocator(),
argumentsAsArray, argumentsAsArray,
numGenericArguments, numGenericArguments,
metadataSize)->getData<char>(); allocationBounds.getTotalSizeInBytes());
// Copy in the metadata template. auto bytes = entry->getData<char>();
memcpy(bytes, metadataTemplate, templateSize); auto addressPoint = bytes + allocationBounds.getAddressPointInBytes();
auto metadata = reinterpret_cast<ClassMetadata *>(addressPoint);
// Zero out the rest of the metadata. initializeClassMetadataFromPattern(metadata, bounds, description, pattern);
memset(bytes + templateSize, 0, metadataSize - templateSize);
// Okay, move to the address point. assert(GenericCacheEntry::getFromMetadata(metadata) == entry);
ClassMetadata *metadata =
reinterpret_cast<ClassMetadata *>(bytes + templateAddressPoint);
auto patternBytes =
reinterpret_cast<const char*>(metadataTemplate) +
templateAddressPoint;
auto patternMetadata = reinterpret_cast<const ClassMetadata*>(patternBytes);
assert(metadata->isTypeMetadata()); assert(metadata->isTypeMetadata());
// Overwrite the superclass field.
metadata->SuperClass = superclass;
// Adjust the relative reference to the nominal type descriptor.
if (!metadata->isArtificialSubclass()) {
metadata->setDescription(patternMetadata->getDescription());
}
// The pattern might have private prefix matter prior to the start
// of metadata.
assert(metadata->getClassAddressPoint() <= templateAddressPoint);
metadata->setClassSize(metadataSize);
return metadata; return metadata;
} }
@@ -241,7 +408,7 @@ swift::swift_getGenericMetadata(const TypeContextDescriptor *description,
[&]() -> GenericCacheEntry* { [&]() -> GenericCacheEntry* {
// Create new metadata to cache. // Create new metadata to cache.
auto metadata = generics.InstantiationFunction(description, arguments); auto metadata = generics.InstantiationFunction(description, arguments);
auto entry = GenericCacheEntry::getFromMetadata(generics, metadata); auto entry = GenericCacheEntry::getFromMetadata(metadata);
entry->Value = metadata; entry->Value = metadata;
return entry; return entry;
}); });
@@ -1475,7 +1642,7 @@ static void _swift_initializeSuperclass(ClassMetadata *theClass) {
_swift_initGenericClassObjCName(theClass); _swift_initGenericClassObjCName(theClass);
#endif #endif
const ClassMetadata *theSuperclass = theClass->SuperClass; const ClassMetadata *theSuperclass = theClass->Superclass;
// Copy the class's immediate methods from the nominal type descriptor // Copy the class's immediate methods from the nominal type descriptor
// to the class metadata. // to the class metadata.
@@ -1509,8 +1676,8 @@ static void _swift_initializeSuperclass(ClassMetadata *theClass) {
// Copy the generic requirements. // Copy the generic requirements.
if (description->isGeneric() if (description->isGeneric()
&& description->getGenericContextHeader().hasArguments()) { && description->getGenericContextHeader().hasArguments()) {
memcpy(classWords + description->getGenericArgumentOffset(ancestor), memcpy(classWords + description->getGenericArgumentOffset(),
superWords + description->getGenericArgumentOffset(ancestor), superWords + description->getGenericArgumentOffset(),
description->getGenericContextHeader().getNumArguments() * description->getGenericContextHeader().getNumArguments() *
sizeof(uintptr_t)); sizeof(uintptr_t));
} }
@@ -1531,7 +1698,7 @@ static void _swift_initializeSuperclass(ClassMetadata *theClass) {
superWords + fieldOffsetVector, superWords + fieldOffsetVector,
description->NumFields * sizeof(uintptr_t)); description->NumFields * sizeof(uintptr_t));
} }
ancestor = ancestor->SuperClass; ancestor = ancestor->Superclass;
} }
#if SWIFT_OBJC_INTEROP #if SWIFT_OBJC_INTEROP
@@ -1540,7 +1707,7 @@ static void _swift_initializeSuperclass(ClassMetadata *theClass) {
auto theMetaclass = (ClassMetadata *)object_getClass((id)theClass); auto theMetaclass = (ClassMetadata *)object_getClass((id)theClass);
auto theSuperMetaclass auto theSuperMetaclass
= (const ClassMetadata *)object_getClass(id_const_cast(theSuperclass)); = (const ClassMetadata *)object_getClass(id_const_cast(theSuperclass));
theMetaclass->SuperClass = theSuperMetaclass; theMetaclass->Superclass = theSuperMetaclass;
#endif #endif
} }
@@ -1556,7 +1723,10 @@ ClassMetadata *
swift::swift_relocateClassMetadata(ClassMetadata *self, swift::swift_relocateClassMetadata(ClassMetadata *self,
size_t templateSize, size_t templateSize,
size_t numImmediateMembers) { size_t numImmediateMembers) {
const ClassMetadata *superclass = self->SuperClass; // Force the initialization of the metadata layout.
(void) self->getDescription()->getMetadataBounds();
const ClassMetadata *superclass = self->Superclass;
size_t metadataSize; size_t metadataSize;
if (superclass && superclass->isTypeMetadata()) { if (superclass && superclass->isTypeMetadata()) {
@@ -1608,7 +1778,7 @@ swift::swift_initClassMetadata_UniversalStrategy(ClassMetadata *self,
// If we have a superclass, start from its size and alignment instead. // If we have a superclass, start from its size and alignment instead.
if (classHasSuperclass(self)) { if (classHasSuperclass(self)) {
const ClassMetadata *super = self->SuperClass; const ClassMetadata *super = self->Superclass;
// This is straightforward if the superclass is Swift. // This is straightforward if the superclass is Swift.
#if SWIFT_OBJC_INTEROP #if SWIFT_OBJC_INTEROP

View File

@@ -190,7 +190,7 @@ public:
/// Check if a class has a formal superclass in the AST. /// Check if a class has a formal superclass in the AST.
static inline static inline
bool classHasSuperclass(const ClassMetadata *c) { bool classHasSuperclass(const ClassMetadata *c) {
return (c->SuperClass && c->SuperClass != getRootSuperclass()); return (c->Superclass && c->Superclass != getRootSuperclass());
} }
/// Replace entries of a freshly-instantiated value witness table with more /// Replace entries of a freshly-instantiated value witness table with more

View File

@@ -470,7 +470,7 @@ recur:
// If the type is a class, try its superclass. // If the type is a class, try its superclass.
if (const ClassMetadata *classType = type->getClassObject()) { if (const ClassMetadata *classType = type->getClassObject()) {
if (classHasSuperclass(classType)) { if (classHasSuperclass(classType)) {
type = getMetadataForClass(classType->SuperClass); type = getMetadataForClass(classType->Superclass);
goto recur; goto recur;
} }
} }
@@ -513,7 +513,7 @@ bool isRelatedType(const Metadata *type, const void *candidate,
// If the type is a class, try its superclass. // If the type is a class, try its superclass.
if (const ClassMetadata *classType = type->getClassObject()) { if (const ClassMetadata *classType = type->getClassObject()) {
if (classHasSuperclass(classType)) { if (classHasSuperclass(classType)) {
type = getMetadataForClass(classType->SuperClass); type = getMetadataForClass(classType->Superclass);
continue; continue;
} }
} }

View File

@@ -563,7 +563,7 @@ auto call(OpaqueValue *passedValue, const Metadata *T, const Metadata *passedTyp
// Look through artificial subclasses. // Look through artificial subclasses.
while (isa->isTypeMetadata() && isa->isArtificialSubclass()) { while (isa->isTypeMetadata() && isa->isArtificialSubclass()) {
isa = isa->SuperClass; isa = isa->Superclass;
} }
passedType = isa; passedType = isa;
} }

View File

@@ -112,7 +112,7 @@ const Metadata *swift::swift_getObjectType(HeapObject *object) {
while (classAsMetadata && classAsMetadata->isTypeMetadata()) { while (classAsMetadata && classAsMetadata->isTypeMetadata()) {
if (!classAsMetadata->isArtificialSubclass()) if (!classAsMetadata->isArtificialSubclass())
return classAsMetadata; return classAsMetadata;
classAsMetadata = classAsMetadata->SuperClass; classAsMetadata = classAsMetadata->Superclass;
} }
id objcObject = reinterpret_cast<id>(object); id objcObject = reinterpret_cast<id>(object);
@@ -195,10 +195,10 @@ static NSString *_getClassDescription(Class cls) {
return _swift_getObjCClassOfAllocated(self); return _swift_getObjCClassOfAllocated(self);
} }
+ (Class)superclass { + (Class)superclass {
return (Class)((const ClassMetadata*) self)->SuperClass; return (Class)((const ClassMetadata*) self)->Superclass;
} }
- (Class)superclass { - (Class)superclass {
return (Class)_swift_getClassOfAllocated(self)->SuperClass; return (Class)_swift_getClassOfAllocated(self)->Superclass;
} }
+ (BOOL)isMemberOfClass:(Class)cls { + (BOOL)isMemberOfClass:(Class)cls {
@@ -289,7 +289,7 @@ static NSString *_getClassDescription(Class cls) {
- (BOOL)isKindOfClass:(Class)someClass { - (BOOL)isKindOfClass:(Class)someClass {
for (auto cls = _swift_getClassOfAllocated(self); cls != nullptr; for (auto cls = _swift_getClassOfAllocated(self); cls != nullptr;
cls = cls->SuperClass) cls = cls->Superclass)
if (cls == (const ClassMetadata*) someClass) if (cls == (const ClassMetadata*) someClass)
return YES; return YES;
@@ -298,7 +298,7 @@ static NSString *_getClassDescription(Class cls) {
+ (BOOL)isSubclassOfClass:(Class)someClass { + (BOOL)isSubclassOfClass:(Class)someClass {
for (auto cls = (const ClassMetadata*) self; cls != nullptr; for (auto cls = (const ClassMetadata*) self; cls != nullptr;
cls = cls->SuperClass) cls = cls->Superclass)
if (cls == (const ClassMetadata*) someClass) if (cls == (const ClassMetadata*) someClass)
return YES; return YES;

View File

@@ -63,14 +63,18 @@ class C<T> : B {}
// CHECK-SAME: i32 {{.*}} @"$S14class_metadata1CCMa" // CHECK-SAME: i32 {{.*}} @"$S14class_metadata1CCMa"
// Superclass. // Superclass.
// CHECK-SAME: i32 {{.*}} @"$S14class_metadata1BCMn" // CHECK-SAME: i32 {{.*}} @"$S14class_metadata1BCMn"
// Negative size in words.
// CHECK-SAME: i32 2,
// Positive size in words.
// CHECK-32-SAME: i32 15,
// CHECK-64-SAME: i32 12,
// Num immediate members.
// CHECK-32-SAME: i32 1,
// Field count. // Field count.
// CHECK-SAME: i32 0, // CHECK-SAME: i32 0,
// Field offset vector offset. // Field offset vector offset.
// CHECK-32-SAME: i32 15, // CHECK-32-SAME: i32 15,
// CHECK-64-SAME: i32 12, // CHECK-64-SAME: i32 12,
// Argument offset.
// CHECK-32-SAME: i32 14,
// CHECK-64-SAME: i32 11,
// Instantiation function. // Instantiation function.
// CHECK-SAME: i32 {{.*}} @"$S14class_metadata1CCMi" // CHECK-SAME: i32 {{.*}} @"$S14class_metadata1CCMi"
// Instantiation cache. // Instantiation cache.

View File

@@ -16,9 +16,11 @@
// CHECK: @"$S16class_resilience14ResilientChildC5fields5Int32VvpWvd" = hidden global [[INT]] {{8|16}} // CHECK: @"$S16class_resilience14ResilientChildC5fields5Int32VvpWvd" = hidden global [[INT]] {{8|16}}
// CHECK: @"$S16class_resilience21ResilientGenericChildCMo" = {{(protected )?}}global [[INT]] 0 // CHECK: @"$S16class_resilience21ResilientGenericChildCMo" = {{(protected )?}}global [[BOUNDS:{ (i32|i64), i32, i32 }]] zeroinitializer
// CHECK: @"$S16class_resilience26ClassWithResilientPropertyCMo" = {{(protected )?}}constant [[INT]] {{52|80}} // CHECK: @"$S16class_resilience26ClassWithResilientPropertyCMo" = {{(protected )?}}constant [[BOUNDS]]
// CHECK-SAME-32: { [[INT]] 52, i32 2, i32 13 }
// CHECK-SAME-64: { [[INT]] 80, i32 2, i32 10 }
// CHECK: @"$S16class_resilience28ClassWithMyResilientPropertyC1rAA0eF6StructVvpWvd" = hidden constant [[INT]] {{8|16}} // CHECK: @"$S16class_resilience28ClassWithMyResilientPropertyC1rAA0eF6StructVvpWvd" = hidden constant [[INT]] {{8|16}}
// CHECK: @"$S16class_resilience28ClassWithMyResilientPropertyC5colors5Int32VvpWvd" = hidden constant [[INT]] {{12|20}} // CHECK: @"$S16class_resilience28ClassWithMyResilientPropertyC5colors5Int32VvpWvd" = hidden constant [[INT]] {{12|20}}
@@ -28,6 +30,8 @@
// CHECK: [[RESILIENTCHILD_NAME:@.*]] = private constant [15 x i8] c"ResilientChild\00" // CHECK: [[RESILIENTCHILD_NAME:@.*]] = private constant [15 x i8] c"ResilientChild\00"
// CHECK: @"$S16class_resilience14ResilientChildCMo" = {{(protected )?}}global [[BOUNDS]] zeroinitializer
// CHECK: @"$S16class_resilience14ResilientChildCMn" = {{(protected )?}}constant <{{.*}}> <{ // CHECK: @"$S16class_resilience14ResilientChildCMn" = {{(protected )?}}constant <{{.*}}> <{
// -- flags: class, unique, reflectable, has vtable, has resilient superclass // -- flags: class, unique, reflectable, has vtable, has resilient superclass
// CHECK-SAME: <i32 0xD004_0050> // CHECK-SAME: <i32 0xD004_0050>
@@ -39,17 +43,23 @@
// CHECK-SAME: i32 3, // CHECK-SAME: i32 3,
// CHECK-SAME: }> // CHECK-SAME: }>
// CHECK: @"$S16class_resilience14ResilientChildCMo" = {{(protected )?}}global [[INT]] 0 // CHECK: @"$S16class_resilience16FixedLayoutChildCMo" = {{(protected )?}}global [[BOUNDS]] zeroinitializer
// CHECK: @"$S16class_resilience16FixedLayoutChildCMo" = {{(protected )?}}global [[INT]] 0 // CHECK: @"$S16class_resilience17MyResilientParentCMo" = {{(protected )?}}constant [[BOUNDS]]
// CHECK-SAME-32: { [[INT]] 52, i32 2, i32 13 }
// CHECK-SAME-64: { [[INT]] 80, i32 2, i32 10 }
// CHECK: @"$S16class_resilience17MyResilientParentCMo" = {{(protected )?}}constant [[INT]] {{52|80}} // CHECK: @"$S16class_resilience16MyResilientChildCMo" = {{(protected )?}}constant [[BOUNDS]]
// CHECK-SAME-32: { [[INT]] 60, i32 2, i32 15 }
// CHECK-SAME-64: { [[INT]] 96, i32 2, i32 12 }
// CHECK: @"$S16class_resilience16MyResilientChildCMo" = {{(protected )?}}constant [[INT]] {{60|96}} // CHECK: @"$S16class_resilience24MyResilientGenericParentCMo" = {{(protected )?}}constant [[BOUNDS]]
// CHECK-SAME-32: { [[INT]] 52, i32 2, i32 13 }
// CHECK-SAME-64: { [[INT]] 80, i32 2, i32 10 }
// CHECK: @"$S16class_resilience24MyResilientGenericParentCMo" = {{(protected )?}}constant [[INT]] {{52|80}} // CHECK: @"$S16class_resilience24MyResilientConcreteChildCMo" = {{(protected )?}}constant [[BOUNDS]]
// CHECK-SAME-32: { [[INT]] 64, i32 2, i32 16 }
// CHECK: @"$S16class_resilience24MyResilientConcreteChildCMo" = {{(protected )?}}constant [[INT]] {{64|104}} // CHECK-SAME-64: { [[INT]] 104, i32 2, i32 13 }
import resilient_class import resilient_class
import resilient_struct import resilient_struct
@@ -273,7 +283,7 @@ extension ResilientGenericOutsideParent {
// CHECK-NEXT: [[ADDR:%.*]] = getelementptr inbounds %T16class_resilience21ResilientGenericChildC, %T16class_resilience21ResilientGenericChildC* %0, i32 0, i32 0, i32 0 // CHECK-NEXT: [[ADDR:%.*]] = getelementptr inbounds %T16class_resilience21ResilientGenericChildC, %T16class_resilience21ResilientGenericChildC* %0, i32 0, i32 0, i32 0
// CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ADDR]] // CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ADDR]]
// CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S16class_resilience21ResilientGenericChildCMo" // CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S16class_resilience21ResilientGenericChildCMo", i32 0, i32 0)
// CHECK-NEXT: [[METADATA_OFFSET:%.*]] = add [[INT]] [[BASE]], {{16|32}} // CHECK-NEXT: [[METADATA_OFFSET:%.*]] = add [[INT]] [[BASE]], {{16|32}}
// CHECK-NEXT: [[ISA_ADDR:%.*]] = bitcast %swift.type* [[ISA]] to i8* // CHECK-NEXT: [[ISA_ADDR:%.*]] = bitcast %swift.type* [[ISA]] to i8*
// CHECK-NEXT: [[FIELD_OFFSET_TMP:%.*]] = getelementptr inbounds i8, i8* [[ISA_ADDR]], [[INT]] [[METADATA_OFFSET]] // CHECK-NEXT: [[FIELD_OFFSET_TMP:%.*]] = getelementptr inbounds i8, i8* [[ISA_ADDR]], [[INT]] [[METADATA_OFFSET]]
@@ -305,7 +315,7 @@ extension ResilientGenericOutsideParent {
// CHECK-LABEL: define{{( protected)?}} swiftcc %swift.type* @"$S15resilient_class29ResilientGenericOutsideParentC0B11_resilienceE22genericExtensionMethodxmyF"(%T15resilient_class29ResilientGenericOutsideParentC* swiftself) #0 { // CHECK-LABEL: define{{( protected)?}} swiftcc %swift.type* @"$S15resilient_class29ResilientGenericOutsideParentC0B11_resilienceE22genericExtensionMethodxmyF"(%T15resilient_class29ResilientGenericOutsideParentC* swiftself) #0 {
// CHECK: [[ISA_ADDR:%.*]] = bitcast %T15resilient_class29ResilientGenericOutsideParentC* %0 to %swift.type** // CHECK: [[ISA_ADDR:%.*]] = bitcast %T15resilient_class29ResilientGenericOutsideParentC* %0 to %swift.type**
// CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]] // CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]]
// CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S15resilient_class29ResilientGenericOutsideParentCMo" // CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S15resilient_class29ResilientGenericOutsideParentCMo", i32 0, i32 0)
// CHECK-NEXT: [[GENERIC_PARAM_OFFSET:%.*]] = add [[INT]] [[BASE]], 0 // CHECK-NEXT: [[GENERIC_PARAM_OFFSET:%.*]] = add [[INT]] [[BASE]], 0
// CHECK-NEXT: [[ISA_TMP:%.*]] = bitcast %swift.type* [[ISA]] to i8* // CHECK-NEXT: [[ISA_TMP:%.*]] = bitcast %swift.type* [[ISA]] to i8*
// CHECK-NEXT: [[GENERIC_PARAM_TMP:%.*]] = getelementptr inbounds i8, i8* [[ISA_TMP]], [[INT]] [[GENERIC_PARAM_OFFSET]] // CHECK-NEXT: [[GENERIC_PARAM_TMP:%.*]] = getelementptr inbounds i8, i8* [[ISA_TMP]], [[INT]] [[GENERIC_PARAM_OFFSET]]
@@ -352,39 +362,21 @@ extension ResilientGenericOutsideParent {
// CHECK-LABEL: define private void @initialize_metadata_ResilientChild(i8*) // CHECK-LABEL: define private void @initialize_metadata_ResilientChild(i8*)
// Get the superclass size and address point...
// CHECK: [[SUPER:%.*]] = call %swift.type* @"$S15resilient_class22ResilientOutsideParentCMa"()
// CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER]] to i8*
// CHECK: [[SIZE_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{36|56}}
// CHECK: [[SIZE_ADDR:%.*]] = bitcast i8* [[SIZE_TMP]] to i32*
// CHECK: [[SIZE:%.*]] = load i32, i32* [[SIZE_ADDR]]
// CHECK: [[ADDRESS_POINT_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{40|60}}
// CHECK: [[ADDRESS_POINT_ADDR:%.*]] = bitcast i8* [[ADDRESS_POINT_TMP]] to i32*
// CHECK: [[ADDRESS_POINT:%.*]] = load i32, i32* [[ADDRESS_POINT_ADDR]]
// CHECK: [[OFFSET:%.*]] = sub i32 [[SIZE]], [[ADDRESS_POINT]]
// Initialize class metadata base offset...
// CHECK-32: store [[INT]] [[OFFSET]], [[INT]]* @"$S16class_resilience14ResilientChildCMo"
// CHECK-64: [[OFFSET_ZEXT:%.*]] = zext i32 [[OFFSET]] to i64
// CHECK-64: store [[INT]] [[OFFSET_ZEXT]], [[INT]]* @"$S16class_resilience14ResilientChildCMo"
// Initialize the superclass field... // Initialize the superclass field...
// CHECK: [[SUPER:%.*]] = call %swift.type* @"$S15resilient_class22ResilientOutsideParentCMa"()
// CHECK: store %swift.type* [[SUPER]], %swift.type** getelementptr inbounds ({{.*}}) // CHECK: store %swift.type* [[SUPER]], %swift.type** getelementptr inbounds ({{.*}})
// Relocate metadata if necessary... // Relocate metadata if necessary...
// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata(%swift.type* {{.*}}, [[INT]] {{60|96}}, [[INT]] 4) // CHECK: [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata(%swift.type* {{.*}}, [[INT]] {{60|96}}, [[INT]] 4)
// Initialize field offset vector... // Initialize field offset vector...
// CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S16class_resilience14ResilientChildCMo" // CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S16class_resilience14ResilientChildCMo", i32 0, i32 0)
// CHECK: [[OFFSET:%.*]] = add [[INT]] [[BASE]], {{12|24}} // CHECK: [[OFFSET:%.*]] = add [[INT]] [[BASE]], {{12|24}}
// CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], [[INT]] 1, i8*** {{.*}}, [[INT]]* {{.*}}) // CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], [[INT]] 1, i8*** {{.*}}, [[INT]]* {{.*}})
// Initialize constructor vtable override... // Initialize constructor vtable override...
// CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S15resilient_class22ResilientOutsideParentCMo" // CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S15resilient_class22ResilientOutsideParentCMo", i32 0, i32 0)
// CHECK: [[OFFSET:%.*]] = add [[INT]] [[BASE]], {{16|32}} // CHECK: [[OFFSET:%.*]] = add [[INT]] [[BASE]], {{16|32}}
// CHECK: [[METADATA_BYTES:%.*]] = bitcast %swift.type* [[METADATA]] to i8* // CHECK: [[METADATA_BYTES:%.*]] = bitcast %swift.type* [[METADATA]] to i8*
// CHECK: [[VTABLE_ENTRY_ADDR:%.*]] = getelementptr inbounds i8, i8* [[METADATA_BYTES]], [[INT]] [[OFFSET]] // CHECK: [[VTABLE_ENTRY_ADDR:%.*]] = getelementptr inbounds i8, i8* [[METADATA_BYTES]], [[INT]] [[OFFSET]]
@@ -392,7 +384,7 @@ extension ResilientGenericOutsideParent {
// CHECK: store i8* bitcast (%T16class_resilience14ResilientChildC* (%T16class_resilience14ResilientChildC*)* @"$S16class_resilience14ResilientChildCACycfc" to i8*), i8** [[VTABLE_ENTRY_TMP]] // CHECK: store i8* bitcast (%T16class_resilience14ResilientChildC* (%T16class_resilience14ResilientChildC*)* @"$S16class_resilience14ResilientChildCACycfc" to i8*), i8** [[VTABLE_ENTRY_TMP]]
// Initialize getValue() vtable override... // Initialize getValue() vtable override...
// CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S15resilient_class22ResilientOutsideParentCMo" // CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S15resilient_class22ResilientOutsideParentCMo", i32 0, i32 0)
// CHECK: [[OFFSET:%.*]] = add [[INT]] [[BASE]], {{28|56}} // CHECK: [[OFFSET:%.*]] = add [[INT]] [[BASE]], {{28|56}}
// CHECK: [[METADATA_BYTES:%.*]] = bitcast %swift.type* [[METADATA]] to i8* // CHECK: [[METADATA_BYTES:%.*]] = bitcast %swift.type* [[METADATA]] to i8*
// CHECK: [[VTABLE_ENTRY_ADDR:%.*]] = getelementptr inbounds i8, i8* [[METADATA_BYTES]], [[INT]] [[OFFSET]] // CHECK: [[VTABLE_ENTRY_ADDR:%.*]] = getelementptr inbounds i8, i8* [[METADATA_BYTES]], [[INT]] [[OFFSET]]
@@ -410,7 +402,7 @@ extension ResilientGenericOutsideParent {
// CHECK-LABEL: define{{( protected)?}} swiftcc i32 @"$S16class_resilience14ResilientChildC5fields5Int32VvgTj"(%T16class_resilience14ResilientChildC* swiftself) // CHECK-LABEL: define{{( protected)?}} swiftcc i32 @"$S16class_resilience14ResilientChildC5fields5Int32VvgTj"(%T16class_resilience14ResilientChildC* swiftself)
// CHECK: [[ISA_ADDR:%.*]] = getelementptr inbounds %T16class_resilience14ResilientChildC, %T16class_resilience14ResilientChildC* %0, i32 0, i32 0, i32 0 // CHECK: [[ISA_ADDR:%.*]] = getelementptr inbounds %T16class_resilience14ResilientChildC, %T16class_resilience14ResilientChildC* %0, i32 0, i32 0, i32 0
// CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]] // CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]]
// CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S16class_resilience14ResilientChildCMo" // CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S16class_resilience14ResilientChildCMo", i32 0, i32 0)
// CHECK-NEXT: [[METADATA_BYTES:%.*]] = bitcast %swift.type* [[ISA]] to i8* // CHECK-NEXT: [[METADATA_BYTES:%.*]] = bitcast %swift.type* [[ISA]] to i8*
// CHECK-NEXT: [[VTABLE_OFFSET_TMP:%.*]] = getelementptr inbounds i8, i8* [[METADATA_BYTES]], [[INT]] [[BASE]] // CHECK-NEXT: [[VTABLE_OFFSET_TMP:%.*]] = getelementptr inbounds i8, i8* [[METADATA_BYTES]], [[INT]] [[BASE]]
// CHECK-NEXT: [[VTABLE_OFFSET_ADDR:%.*]] = bitcast i8* [[VTABLE_OFFSET_TMP]] to i32 (%T16class_resilience14ResilientChildC*)** // CHECK-NEXT: [[VTABLE_OFFSET_ADDR:%.*]] = bitcast i8* [[VTABLE_OFFSET_TMP]] to i32 (%T16class_resilience14ResilientChildC*)**
@@ -423,7 +415,7 @@ extension ResilientGenericOutsideParent {
// CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S16class_resilience14ResilientChildC5fields5Int32VvsTj"(i32, %T16class_resilience14ResilientChildC* swiftself) // CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S16class_resilience14ResilientChildC5fields5Int32VvsTj"(i32, %T16class_resilience14ResilientChildC* swiftself)
// CHECK: [[ISA_ADDR:%.*]] = getelementptr inbounds %T16class_resilience14ResilientChildC, %T16class_resilience14ResilientChildC* %1, i32 0, i32 0, i32 0 // CHECK: [[ISA_ADDR:%.*]] = getelementptr inbounds %T16class_resilience14ResilientChildC, %T16class_resilience14ResilientChildC* %1, i32 0, i32 0, i32 0
// CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]] // CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]]
// CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S16class_resilience14ResilientChildCMo" // CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S16class_resilience14ResilientChildCMo", i32 0, i32 0)
// CHECK-NEXT: [[METADATA_OFFSET:%.*]] = add [[INT]] [[BASE]], {{4|8}} // CHECK-NEXT: [[METADATA_OFFSET:%.*]] = add [[INT]] [[BASE]], {{4|8}}
// CHECK-NEXT: [[METADATA_BYTES:%.*]] = bitcast %swift.type* [[ISA]] to i8* // CHECK-NEXT: [[METADATA_BYTES:%.*]] = bitcast %swift.type* [[ISA]] to i8*
// CHECK-NEXT: [[VTABLE_OFFSET_TMP:%.*]] = getelementptr inbounds i8, i8* [[METADATA_BYTES]], [[INT]] [[METADATA_OFFSET]] // CHECK-NEXT: [[VTABLE_OFFSET_TMP:%.*]] = getelementptr inbounds i8, i8* [[METADATA_BYTES]], [[INT]] [[METADATA_OFFSET]]
@@ -437,26 +429,8 @@ extension ResilientGenericOutsideParent {
// CHECK-LABEL: define private void @initialize_metadata_FixedLayoutChild(i8*) // CHECK-LABEL: define private void @initialize_metadata_FixedLayoutChild(i8*)
// Get the superclass size and address point...
// CHECK: [[SUPER:%.*]] = call %swift.type* @"$S15resilient_class22ResilientOutsideParentCMa"()
// CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER]] to i8*
// CHECK: [[SIZE_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{36|56}}
// CHECK: [[SIZE_ADDR:%.*]] = bitcast i8* [[SIZE_TMP]] to i32*
// CHECK: [[SIZE:%.*]] = load i32, i32* [[SIZE_ADDR]]
// CHECK: [[ADDRESS_POINT_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{40|60}}
// CHECK: [[ADDRESS_POINT_ADDR:%.*]] = bitcast i8* [[ADDRESS_POINT_TMP]] to i32*
// CHECK: [[ADDRESS_POINT:%.*]] = load i32, i32* [[ADDRESS_POINT_ADDR]]
// CHECK: [[OFFSET:%.*]] = sub i32 [[SIZE]], [[ADDRESS_POINT]]
// Initialize class metadata base offset...
// CHECK-32: store [[INT]] [[OFFSET]], [[INT]]* @"$S16class_resilience16FixedLayoutChildCMo"
// CHECK-64: [[OFFSET_ZEXT:%.*]] = zext i32 [[OFFSET]] to i64
// CHECK-64: store [[INT]] [[OFFSET_ZEXT]], [[INT]]* @"$S16class_resilience16FixedLayoutChildCMo"
// Initialize the superclass field... // Initialize the superclass field...
// CHECK: [[SUPER:%.*]] = call %swift.type* @"$S15resilient_class22ResilientOutsideParentCMa"()
// CHECK: store %swift.type* [[SUPER]], %swift.type** getelementptr inbounds ({{.*}}) // CHECK: store %swift.type* [[SUPER]], %swift.type** getelementptr inbounds ({{.*}})
// Relocate metadata if necessary... // Relocate metadata if necessary...
@@ -471,23 +445,14 @@ extension ResilientGenericOutsideParent {
// Get the superclass size and address point... // Get the superclass size and address point...
// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** bitcast ({{.*}} @"$S16class_resilience21ResilientGenericChildCMP" to i8**))
// Initialize the superclass pointer...
// CHECK: [[SUPER:%.*]] = call %swift.type* @"$S15resilient_class29ResilientGenericOutsideParentCMa"(%swift.type* %T) // CHECK: [[SUPER:%.*]] = call %swift.type* @"$S15resilient_class29ResilientGenericOutsideParentCMa"(%swift.type* %T)
// CHECK: [[SUPER_TMP:%.*]] = bitcast %swift.type* [[SUPER]] to %objc_class* // CHECK: [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to %swift.type**
// CHECK: [[SUPER_ADDR:%.*]] = bitcast %objc_class* [[SUPER_TMP]] to i8* // CHECK: [[SUPER_ADDR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i32 1
// CHECK: [[SIZE_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{36|56}} // CHECK: store %swift.type* [[SUPER]], %swift.type** [[SUPER_ADDR]],
// CHECK: [[SIZE_ADDR:%.*]] = bitcast i8* [[SIZE_TMP]] to i32*
// CHECK: [[SIZE:%.*]] = load i32, i32* [[SIZE_ADDR]]
// CHECK: [[ADDRESS_POINT_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{40|60}}
// CHECK: [[ADDRESS_POINT_ADDR:%.*]] = bitcast i8* [[ADDRESS_POINT_TMP]] to i32*
// CHECK: [[ADDRESS_POINT:%.*]] = load i32, i32* [[ADDRESS_POINT_ADDR]]
// CHECK: [[OFFSET:%.*]] = sub i32 [[SIZE]], [[ADDRESS_POINT]] // CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]],
// Initialize class metadata base offset...
// CHECK-32: store [[INT]] [[OFFSET]], [[INT]]* @"$S16class_resilience21ResilientGenericChildCMo"
// CHECK-64: [[OFFSET_ZEXT:%.*]] = zext i32 [[OFFSET]] to i64
// CHECK-64: store [[INT]] [[OFFSET_ZEXT]], [[INT]]* @"$S16class_resilience21ResilientGenericChildCMo"
// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** bitcast ({{.*}} @"$S16class_resilience21ResilientGenericChildCMP" to i8**), [[INT]] {{[0-9]+}}, [[INT]] {{[0-9]+}}, i8** %1, %objc_class* [[SUPER_TMP]], [[INT]] 5)
// CHECK: ret %swift.type* [[METADATA]] // CHECK: ret %swift.type* [[METADATA]]

View File

@@ -116,8 +116,6 @@ import Swift
// CHECK-SAME: i32 1, // CHECK-SAME: i32 1,
// -- No empty cases // -- No empty cases
// CHECK-SAME: i32 0, // CHECK-SAME: i32 0,
// -- Case type accessor
// CHECK-SAME: i32 2,
// -- generic instantiation function // -- generic instantiation function
// CHECK-SAME: @"$S4enum16DynamicSingletonOMi" // CHECK-SAME: @"$S4enum16DynamicSingletonOMi"
// -- generic parameters, requirements, key, extra // -- generic parameters, requirements, key, extra

View File

@@ -19,12 +19,16 @@ import Swift
// CHECK-SAME: <i32 0x8004_00D0> // CHECK-SAME: <i32 0x8004_00D0>
// -- name // -- name
// CHECK-SAME: [12 x i8]* [[ROOTGENERIC_NAME]] // CHECK-SAME: [12 x i8]* [[ROOTGENERIC_NAME]]
// -- negative size in words
// CHECK-SAME: i32 2,
// -- positive size in words
// CHECK-SAME: i32 18,
// -- num immediate members
// CHECK-SAME: i32 8,
// -- num fields // -- num fields
// CHECK-SAME: i32 3, // CHECK-SAME: i32 3,
// -- field offset vector offset // -- field offset vector offset
// CHECK-SAME: i32 15, // CHECK-SAME: i32 15,
// -- generic parameter vector offset
// CHECK-SAME: i32 10,
// -- template instantiation function // -- template instantiation function
// CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**)* @"$S15generic_classes11RootGenericCMi" // CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**)* @"$S15generic_classes11RootGenericCMi"
// -- template instantiation cache // -- template instantiation cache
@@ -38,10 +42,29 @@ import Swift
// CHECK-SAME: } // CHECK-SAME: }
// CHECK-LABEL: @"$S15generic_classes11RootGenericCMP" = internal constant // CHECK-LABEL: @"$S15generic_classes11RootGenericCMP" = internal constant
// -- nominal type descriptor // CHECK-SAME: <{
// CHECK-SAME: @"$S15generic_classes11RootGenericCMn" // -- heap destructor
// CHECK-SAME: @"$S15generic_classes11RootGenericCfD"
// -- ivar destroyer // -- ivar destroyer
// CHECK-SAME: i8* null // CHECK-SAME: i8* null,
// -- flags
// CHECK_SAME: i32 3,
// -- immediate pattern size
// CHECK-SAME: i16 0,
// -- immediate pattern target offset
// CHECK-SAME: i16 0,
// -- extra data size
// CHECK-SAME-native: i16 0,
// CHECK-SAME-objc: i16 23,
// -- class ro-data offset
// CHECK-SAME-native: i16 0,
// CHECK-SAME-objc: i16 5,
// -- metaclass object offset
// CHECK-SAME-native: i16 0,
// CHECK-SAME-objc: i16 0,
// -- class ro-data offset
// CHECK-SAME-native: i16 0
// CHECK-SAME-objc: i16 14,
// CHECK-SAME: }> // CHECK-SAME: }>
// -- Check that offset vars are emitted for fixed-layout generics // -- Check that offset vars are emitted for fixed-layout generics
@@ -87,10 +110,28 @@ import Swift
// CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**)* @"$S15generic_classes015GenericInheritsC0CMi" // CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**)* @"$S15generic_classes015GenericInheritsC0CMi"
// CHECK: @"$S15generic_classes015GenericInheritsC0CMP" = internal constant // CHECK: @"$S15generic_classes015GenericInheritsC0CMP" = internal constant
// -- nominal type descriptor // -- heap destructor
// CHECK-SAME: @"$S15generic_classes015GenericInheritsC0CMn", // CHECK-SAME: @"$S15generic_classes015GenericInheritsC0CfD"
// -- ivar destroyer // -- ivar destroyer
// CHECK-SAME: i8* null // CHECK-SAME: i8* null,
// -- flags
// CHECK_SAME: i32 3,
// -- immediate pattern size
// CHECK-SAME: i16 0,
// -- immediate pattern target offset
// CHECK-SAME: i16 0,
// -- extra data size
// CHECK-SAME-native: i16 0,
// CHECK-SAME-objc: i16 23,
// -- class ro-data offset
// CHECK-SAME-native: i16 0,
// CHECK-SAME-objc: i16 5,
// -- metaclass object offset
// CHECK-SAME-native: i16 0,
// CHECK-SAME-objc: i16 0,
// -- class ro-data offset
// CHECK-SAME-native: i16 0
// CHECK-SAME-objc: i16 14,
// CHECK-SAME: } // CHECK-SAME: }
// CHECK: @"$S15generic_classes018GenericInheritsNonC0CMP" // CHECK: @"$S15generic_classes018GenericInheritsNonC0CMP"
@@ -292,13 +333,13 @@ entry(%c : $RootGeneric<Int32>):
*/ */
// CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_classes11RootGenericCMi"(%swift.type_descriptor*, i8**) {{.*}} { // CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_classes11RootGenericCMi"(%swift.type_descriptor*, i8**) {{.*}} {
// CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, {{.*}}, i64 8) // CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, {{.*}} @"$S15generic_classes11RootGenericCMP"{{.*}})
// -- initialize the dependent field offsets // -- initialize the dependent field offsets
// CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 3, i8*** {{%.*}}, i64* {{%.*}}) // CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 3, i8*** {{%.*}}, i64* {{%.*}})
// CHECK: } // CHECK: }
// CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_classes22RootGenericFixedLayoutCMi"(%swift.type_descriptor*, i8**) {{.*}} { // CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_classes22RootGenericFixedLayoutCMi"(%swift.type_descriptor*, i8**) {{.*}} {
// CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, {{.*}}, i64 5) // CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, {{.*}} @"$S15generic_classes22RootGenericFixedLayoutCMP"{{.*}})
// CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 3, i8*** {{%.*}}, i64* {{%.*}}) // CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 3, i8*** {{%.*}}, i64* {{%.*}})
// CHECK: } // CHECK: }
@@ -309,10 +350,7 @@ entry(%c : $RootGeneric<Int32>):
// CHECK: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i32 1 // CHECK: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i32 1
// CHECK: %B = load %swift.type*, %swift.type** [[T1]] // CHECK: %B = load %swift.type*, %swift.type** [[T1]]
// Construct the superclass. // Construct the superclass.
// CHECK: [[SUPER:%.*]] = call %swift.type* @"$S15generic_classes11RootGenericCMa"(%swift.type* %A) // CHECK: [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, {{.*}} @"$S15generic_classes015GenericInheritsC0CMP"{{.*}})
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[SUPER]] to %objc_class*
// CHECK-native: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** {{.*}}, i64 96, i64 16, i8** %1, %objc_class* [[T0]], i64 6)
// CHECK-objc: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** {{.*}}, i64 280, i64 200, i8** %1, %objc_class* [[T0]], i64 6)
// CHECK: [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8** // CHECK: [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
// Put the generic arguments in their correct positions. // Put the generic arguments in their correct positions.
// CHECK: [[A_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY:%.*]], i64 18 // CHECK: [[A_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY:%.*]], i64 18
@@ -321,26 +359,10 @@ entry(%c : $RootGeneric<Int32>):
// CHECK: [[B_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY:%.*]], i64 19 // CHECK: [[B_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY:%.*]], i64 19
// CHECK: [[T0:%.*]] = bitcast %swift.type* %B to i8* // CHECK: [[T0:%.*]] = bitcast %swift.type* %B to i8*
// CHECK: store i8* [[T0]], i8** [[B_ADDR]], align 8 // CHECK: store i8* [[T0]], i8** [[B_ADDR]], align 8
// Set up the isa. // CHECK: [[SUPER:%.*]] ={{( tail)?}} call %swift.type* @"$S15generic_classes11RootGenericCMa"(%swift.type* %A)
// CHECK-objc: [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8** // CHECK: [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to %swift.type**
// CHECK-objc: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 0 // CHECK: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i32 1
// CHECK-objc: [[T1:%.*]] = bitcast i8** [[T0]] to %objc_class** // CHECK: store %swift.type* [[SUPER]], %swift.type** [[T1]],
// CHECK-objc: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 -25
// CHECK-objc: [[METACLASS:%.*]] = bitcast i8** [[T0]] to %objc_class*
// CHECK-objc: store %objc_class* [[METACLASS]], %objc_class** [[T1]], align 8
// Set up the instance rodata pointer.
// CHECK-objc: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 4
// CHECK-objc: [[T1:%.*]] = bitcast i8** [[T0]] to i64*
// CHECK-objc: [[RODATA:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 -20
// CHECK-objc: [[T2:%.*]] = ptrtoint i8** [[RODATA]] to i64
// CHECK-objc: [[T3:%.*]] = or i64 [[T2]], 1
// CHECK-objc: store i64 [[T3]], i64* [[T1]], align 8
// Set up the class rodata pointer.
// CHECK-objc: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 -21
// CHECK-objc: [[T1:%.*]] = bitcast i8** [[T0]] to i64*
// CHECK-objc: [[META_RODATA:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 -11
// CHECK-objc: [[T2:%.*]] = ptrtoint i8** [[META_RODATA]] to i64
// CHECK-objc: store i64 [[T2]], i64* [[T1]], align 8
// Initialize our own dependent field offsets. // Initialize our own dependent field offsets.
// CHECK: [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i64* // CHECK: [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i64*
// CHECK: [[OFFSETS:%.*]] = getelementptr inbounds i64, i64* [[METADATA_ARRAY]], i64 23 // CHECK: [[OFFSETS:%.*]] = getelementptr inbounds i64, i64* [[METADATA_ARRAY]], i64 23

View File

@@ -29,8 +29,6 @@ import Builtin
// CHECK-SAME: i32 1, // CHECK-SAME: i32 1,
// -- field offset vector offset // -- field offset vector offset
// CHECK-SAME: i32 3, // CHECK-SAME: i32 3,
// -- generic parameter vector offset
// CHECK-SAME: i32 2,
// -- generic instantiation info // -- generic instantiation info
// CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**)* @"$S15generic_structs13SingleDynamicVMi" // CHECK-SAME: %swift.type* (%swift.type_descriptor*, i8**)* @"$S15generic_structs13SingleDynamicVMi"
// CHECK-SAME: [{{[0-9]+}} x i8*]* @"$S15generic_structs13SingleDynamicVMI" // CHECK-SAME: [{{[0-9]+}} x i8*]* @"$S15generic_structs13SingleDynamicVMI"
@@ -59,8 +57,6 @@ import Builtin
// CHECK-SAME: i32 2, // CHECK-SAME: i32 2,
// -- field offset vector offset // -- field offset vector offset
// CHECK-SAME: i32 6, // CHECK-SAME: i32 6,
// -- generic parameter vector offset
// CHECK-SAME: i32 2,
// -- generic params, requirements, key args, extra args // -- generic params, requirements, key args, extra args
// CHECK-SAME: i32 2, i32 2, i32 2, i32 2, // CHECK-SAME: i32 2, i32 2, i32 2, i32 2,
// -- generic parameters // -- generic parameters

View File

@@ -11,30 +11,43 @@
// CHECK-LABEL: @"$S13generic_types1ACMI" = internal global [16 x i8*] zeroinitializer, align 8 // CHECK-LABEL: @"$S13generic_types1ACMI" = internal global [16 x i8*] zeroinitializer, align 8
// CHECK-LABEL: @"$S13generic_types1ACMn" = hidden constant // CHECK-LABEL: @"$S13generic_types1ACMn" = hidden constant
// CHECK-SAME: i32 -2147221296,
// CHECK-SAME: @"$S13generic_typesMXM"
// <name>
// CHECK-SAME: @"$S13generic_types1ACMa" // CHECK-SAME: @"$S13generic_types1ACMa"
// -- superclass
// CHECK-SAME: i32 0,
// -- negative size in words
// CHECK-SAME: i32 2,
// -- positive size in words
// CHECK-SAME: i32 17,
// -- num immediate members
// CHECK-SAME: i32 7,
// -- num fields
// CHECK-SAME: i32 1,
// -- field offset vector offset
// CHECK-SAME: i32 16,
// -- instantiation function
// CHECK-SAME: @"$S13generic_types1ACMi" // CHECK-SAME: @"$S13generic_types1ACMi"
// -- instantiation cache
// CHECK-SAME: @"$S13generic_types1ACMI" // CHECK-SAME: @"$S13generic_types1ACMI"
// -- num generic params
// CHECK-SAME: i32 1,
// -- num generic requirement
// CHECK-SAME: i32 0,
// -- num key arguments
// CHECK-SAME: i32 1,
// -- num extra arguments
// CHECK-SAME: i32 0,
// -- parameter descriptor 1
// CHECK-SAME: i8 -128,
// CHECK-LABEL: @"$S13generic_types1ACMP" = internal constant // CHECK-LABEL: @"$S13generic_types1ACMP" = internal constant
// CHECK-SAME: void ([[A]]*)* @"$S13generic_types1ACfD", // CHECK-SAME: void ([[A]]*)* @"$S13generic_types1ACfD",
// CHECK-SAME: i8** @"$SBoWV",
// CHECK-SAME: i64 0,
// CHECK-SAME: %swift.type* null,
// CHECK-native-SAME: %swift.opaque* null,
// CHECK-objc-SAME: %swift.opaque* @_objc_empty_cache,
// CHECK-SAME: %swift.opaque* null,
// CHECK-SAME: i64 {{1|2}},
// CHECK-SAME: i32 {{3|2}},
// CHECK-SAME: i32 0,
// CHECK-SAME: i32 24,
// CHECK-SAME: i16 7,
// CHECK-SAME: i16 0,
// CHECK-SAME: i32 152,
// CHECK-SAME: i32 16,
// -- nominal type descriptor
// CHECK-SAME: @"$S13generic_types1ACMn",
// -- ivar destroyer // -- ivar destroyer
// CHECK-SAME: i8* null // CHECK-SAME: i8* null,
// -- flags
// CHECK-SAME: i32 {{3|2}},
// CHECK-SAME: } // CHECK-SAME: }
// CHECK-LABEL: @"$S13generic_types1BCMI" = internal global [16 x i8*] zeroinitializer, align 8 // CHECK-LABEL: @"$S13generic_types1BCMI" = internal global [16 x i8*] zeroinitializer, align 8
@@ -46,77 +59,29 @@
// CHECK-LABEL: @"$S13generic_types1BCMP" = internal constant // CHECK-LABEL: @"$S13generic_types1BCMP" = internal constant
// CHECK-SAME: void ([[B]]*)* @"$S13generic_types1BCfD", // CHECK-SAME: void ([[B]]*)* @"$S13generic_types1BCfD",
// CHECK-SAME: i8** @"$SBoWV",
// CHECK-SAME: i64 0,
// CHECK-SAME: %swift.type* null,
// CHECK-native-SAME: %swift.opaque* null,
// CHECK-objc-SAME: %swift.opaque* @_objc_empty_cache,
// CHECK-SAME: %swift.opaque* null,
// CHECK-SAME: i64 {{1|2}},
// CHECK-SAME: i32 {{3|2}},
// CHECK-SAME: i32 0,
// CHECK-SAME: i32 24,
// CHECK-SAME: i16 7,
// CHECK-SAME: i16 0,
// CHECK-SAME: i32 144,
// CHECK-SAME: i32 16,
// -- nominal type descriptor
// CHECK-SAME: @"$S13generic_types1BCMn",
// -- ivar destroyer // -- ivar destroyer
// CHECK-SAME: i8* null // CHECK-SAME: i8* null
// CHECK-SAME: i32 {{3|2}},
// CHECK-SAME: } // CHECK-SAME: }
// CHECK-LABEL: @"$S13generic_types1CCMP" = internal constant // CHECK-LABEL: @"$S13generic_types1CCMP" = internal constant
// CHECK-SAME: void ([[C]]*)* @"$S13generic_types1CCfD", // CHECK-SAME: void ([[C]]*)* @"$S13generic_types1CCfD",
// CHECK-SAME: i8** @"$SBoWV",
// CHECK-SAME: i64 0,
// CHECK-SAME: %swift.type* null,
// CHECK-native-SAME: %swift.opaque* null,
// CHECK-objc-SAME: %swift.opaque* @_objc_empty_cache,
// CHECK-SAME: %swift.opaque* null,
// CHECK-SAME: i64 {{1|2}},
// CHECK-SAME: i32 {{3|2}},
// CHECK-SAME: i32 0,
// CHECK-SAME: i32 24,
// CHECK-SAME: i16 7,
// CHECK-SAME: i16 0,
// CHECK-SAME: i32 160,
// CHECK-SAME: i32 16,
// -- nominal type descriptor
// CHECK-SAME: @"$S13generic_types1CCMn",
// -- ivar destroyer // -- ivar destroyer
// CHECK-SAME: i8* null // CHECK-SAME: i8* null
// CHECK-SAME: i32 {{3|2}},
// CHECK-SAME: } // CHECK-SAME: }
// CHECK-LABEL: @"$S13generic_types1DCMP" = internal constant // CHECK-LABEL: @"$S13generic_types1DCMP" = internal constant
// CHECK-SAME: void ([[D]]*)* @"$S13generic_types1DCfD", // CHECK-SAME: void ([[D]]*)* @"$S13generic_types1DCfD",
// CHECK-SAME: i8** @"$SBoWV",
// CHECK-SAME: i64 0,
// CHECK-SAME: %swift.type* null,
// CHECK-native-SAME: %swift.opaque* null,
// CHECK-objc-SAME: %swift.opaque* @_objc_empty_cache,
// CHECK-SAME: %swift.opaque* null,
// CHECK-SAME: i64 {{1|2}},
// CHECK-SAME: i32 {{3|2}},
// CHECK-SAME: i32 0,
// CHECK-SAME: i32 24,
// CHECK-SAME: i16 7,
// CHECK-SAME: i16 0,
// CHECK-SAME: i32 160,
// CHECK-SAME: i32 16,
// -- nominal type descriptor
// CHECK-SAME: @"$S13generic_types1DCMn",
// -- ivar destroyer // -- ivar destroyer
// CHECK-SAME: i8* null // CHECK-SAME: i8* null
// CHECK-SAME: i32 {{3|2}},
// CHECK-SAME: } // CHECK-SAME: }
// CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S13generic_types1ACMi"(%swift.type_descriptor*, i8**) {{.*}} { // CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S13generic_types1ACMi"(%swift.type_descriptor*, i8**) {{.*}} {
// CHECK: [[T0:%.*]] = bitcast i8** %1 to %swift.type** // CHECK: [[T0:%.*]] = bitcast i8** %1 to %swift.type**
// CHECK: %T = load %swift.type*, %swift.type** [[T0]], // CHECK: %T = load %swift.type*, %swift.type** [[T0]],
// CHECK-native: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** bitcast ({{.*}}* @"$S13generic_types1ACMP" to i8**), i64 96, i64 16, i8** %1, %objc_class* null, i64 7) // CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** bitcast ({{.*}}* @"$S13generic_types1ACMP" to i8**))
// CHECK-objc: [[T0:%.*]] = load %objc_class*, %objc_class** @"OBJC_CLASS_REF_$__TtCs12_SwiftObject"
// CHECK-objc: [[SUPER:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* [[T0]])
// CHECK-objc: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** bitcast ({{.*}}* @"$S13generic_types1ACMP" to i8**), i64 280, i64 200, i8** %1, %objc_class* [[SUPER]], i64 7)
// CHECK: [[SELF_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8** // CHECK: [[SELF_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
// CHECK: [[T1:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i64 10 // CHECK: [[T1:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i64 10
// CHECK: [[T0:%.*]] = bitcast %swift.type* %T to i8* // CHECK: [[T0:%.*]] = bitcast %swift.type* %T to i8*
@@ -127,10 +92,7 @@
// CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S13generic_types1BCMi"(%swift.type_descriptor*, i8**) {{.*}} { // CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S13generic_types1BCMi"(%swift.type_descriptor*, i8**) {{.*}} {
// CHECK: [[T0:%.*]] = bitcast i8** %1 to %swift.type** // CHECK: [[T0:%.*]] = bitcast i8** %1 to %swift.type**
// CHECK: %T = load %swift.type*, %swift.type** [[T0]], // CHECK: %T = load %swift.type*, %swift.type** [[T0]],
// CHECK-native: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** bitcast ({{.*}}* @"$S13generic_types1BCMP" to i8**), i64 96, i64 16, i8** %1, %objc_class* null, i64 6) // CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** bitcast ({{.*}}* @"$S13generic_types1BCMP" to i8**))
// CHECK-objc: [[T0:%.*]] = load %objc_class*, %objc_class** @"OBJC_CLASS_REF_$__TtCs12_SwiftObject"
// CHECK-objc: [[SUPER:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* [[T0]])
// CHECK-objc: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** bitcast ({{.*}}* @"$S13generic_types1BCMP" to i8**), i64 280, i64 200, i8** %1, %objc_class* [[SUPER]], i64 6)
// CHECK: [[SELF_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8** // CHECK: [[SELF_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
// CHECK: [[T1:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i64 10 // CHECK: [[T1:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i64 10
// CHECK: [[T0:%.*]] = bitcast %swift.type* %T to i8* // CHECK: [[T0:%.*]] = bitcast %swift.type* %T to i8*

View File

@@ -63,8 +63,6 @@ public class Concrete : Derived<Int> {
//// instantiation time. //// instantiation time.
// CHECK-LABEL: @"$S14generic_vtable7DerivedCMP" = internal constant <{{.*}}> <{ // CHECK-LABEL: @"$S14generic_vtable7DerivedCMP" = internal constant <{{.*}}> <{
// -- nominal type descriptor
// CHECK-SAME: @"$S14generic_vtable7DerivedCMn",
// -- ivar destroyer // -- ivar destroyer
// CHECK-SAME: i8* null // CHECK-SAME: i8* null
// -- // --
@@ -105,7 +103,7 @@ public class Concrete : Derived<Int> {
// - 2 immediate members: // - 2 immediate members:
// - type metadata for generic parameter T, // - type metadata for generic parameter T,
// - and vtable entry for 'm3()' // - and vtable entry for 'm3()'
// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** bitcast ({{.*}} @"$S14generic_vtable7DerivedCMP" to i8**), i64 {{[0-9]+}}, i64 {{[0-9]+}}, i8** %1, {{.*}}, i64 2) // CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** bitcast ({{.*}} @"$S14generic_vtable7DerivedCMP" to i8**))
// CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 0, {{.*}}) // CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 0, {{.*}})

View File

@@ -54,7 +54,7 @@ bb0(%0 : $ChildToResilientParent):
// ChildToResilientParent is in our resilience domain - can load the superclass's metadata directly. // ChildToResilientParent is in our resilience domain - can load the superclass's metadata directly.
// CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S5super22ChildToResilientParentC6methodyyF"(%T5super22ChildToResilientParentC* swiftself) // CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S5super22ChildToResilientParentC6methodyyF"(%T5super22ChildToResilientParentC* swiftself)
// CHECK: [[SUPER_METADATA:%.*]] = call %swift.type* @"$S15resilient_class22ResilientOutsideParentCMa"() // CHECK: [[SUPER_METADATA:%.*]] = call %swift.type* @"$S15resilient_class22ResilientOutsideParentCMa"()
// CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S15resilient_class22ResilientOutsideParentCMo" // CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS:{.*}]], {{.*}}* @"$S15resilient_class22ResilientOutsideParentCMo", i32 0, i32 0)
// CHECK: [[VTABLE_OFFSET:%.*]] = add [[INT]] [[BASE]], {{20|40}} // CHECK: [[VTABLE_OFFSET:%.*]] = add [[INT]] [[BASE]], {{20|40}}
// CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER_METADATA]] to i8* // CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER_METADATA]] to i8*
// CHECK: [[VTABLE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], [[INT]] [[VTABLE_OFFSET]] // CHECK: [[VTABLE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], [[INT]] [[VTABLE_OFFSET]]
@@ -76,7 +76,7 @@ bb0(%0 : $@thick ChildToResilientParent.Type):
// ChildToResilientParent is in our resilience domain - can load the superclass's metadata directly. // ChildToResilientParent is in our resilience domain - can load the superclass's metadata directly.
// CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S5super22ChildToResilientParentC11classMethodyyFZ"(%swift.type* swiftself) // CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S5super22ChildToResilientParentC11classMethodyyFZ"(%swift.type* swiftself)
// CHECK: [[SUPER_METADATA:%.*]] = call %swift.type* @"$S15resilient_class22ResilientOutsideParentCMa"() // CHECK: [[SUPER_METADATA:%.*]] = call %swift.type* @"$S15resilient_class22ResilientOutsideParentCMa"()
// CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S15resilient_class22ResilientOutsideParentCMo" // CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S15resilient_class22ResilientOutsideParentCMo", i32 0, i32 0)
// CHECK: [[VTABLE_OFFSET:%.*]] = add [[INT]] [[BASE]], {{24|48}} // CHECK: [[VTABLE_OFFSET:%.*]] = add [[INT]] [[BASE]], {{24|48}}
// CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER_METADATA]] to i8* // CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER_METADATA]] to i8*
// CHECK: [[VTABLE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], [[INT]] [[VTABLE_OFFSET]] // CHECK: [[VTABLE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], [[INT]] [[VTABLE_OFFSET]]
@@ -151,7 +151,7 @@ bb0(%0 : $ResilientOutsideChild):
// CHECK: [[OPAQUE_METADATA:%.*]] = bitcast %swift.type* [[METADATA]] to %swift.type** // CHECK: [[OPAQUE_METADATA:%.*]] = bitcast %swift.type* [[METADATA]] to %swift.type**
// CHECK: [[SUPER_METADATA_PTR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[OPAQUE_METADATA]], i32 1 // CHECK: [[SUPER_METADATA_PTR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[OPAQUE_METADATA]], i32 1
// CHECK: [[SUPER_METADATA:%.*]] = load %swift.type*, %swift.type** [[SUPER_METADATA_PTR]] // CHECK: [[SUPER_METADATA:%.*]] = load %swift.type*, %swift.type** [[SUPER_METADATA_PTR]]
// CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S15resilient_class22ResilientOutsideParentCMo" // CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S15resilient_class22ResilientOutsideParentCMo", i32 0, i32 0)
// CHECK: [[VTABLE_OFFSET:%.*]] = add [[INT]] [[BASE]], {{20|40}} // CHECK: [[VTABLE_OFFSET:%.*]] = add [[INT]] [[BASE]], {{20|40}}
// CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER_METADATA]] to i8* // CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER_METADATA]] to i8*
// CHECK: [[VTABLE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], [[INT]] [[VTABLE_OFFSET]] // CHECK: [[VTABLE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], [[INT]] [[VTABLE_OFFSET]]
@@ -177,7 +177,7 @@ bb0(%0 : $@thick ResilientOutsideChild.Type):
// CHECK: [[OPAQUE_METADATA:%.*]] = bitcast %swift.type* [[METADATA]] to %swift.type** // CHECK: [[OPAQUE_METADATA:%.*]] = bitcast %swift.type* [[METADATA]] to %swift.type**
// CHECK: [[SUPER_METADATA_PTR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[OPAQUE_METADATA]], i32 1 // CHECK: [[SUPER_METADATA_PTR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[OPAQUE_METADATA]], i32 1
// CHECK: [[SUPER_METADATA:%.*]] = load %swift.type*, %swift.type** [[SUPER_METADATA_PTR]] // CHECK: [[SUPER_METADATA:%.*]] = load %swift.type*, %swift.type** [[SUPER_METADATA_PTR]]
// CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S15resilient_class22ResilientOutsideParentCMo" // CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S15resilient_class22ResilientOutsideParentCMo", i32 0, i32 0)
// CHECK: [[VTABLE_OFFSET:%.*]] = add [[INT]] [[BASE]], {{24|48}} // CHECK: [[VTABLE_OFFSET:%.*]] = add [[INT]] [[BASE]], {{24|48}}
// CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER_METADATA]] to i8* // CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER_METADATA]] to i8*
// CHECK: [[VTABLE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], [[INT]] [[VTABLE_OFFSET]] // CHECK: [[VTABLE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], [[INT]] [[VTABLE_OFFSET]]

View File

@@ -80,8 +80,7 @@ static SWIFT_CC(swift) void destroyTestObject(SWIFT_CONTEXT HeapObject *_object)
static const FullMetadata<ClassMetadata> TestClassObjectMetadata = { static const FullMetadata<ClassMetadata> TestClassObjectMetadata = {
{ { &destroyTestObject }, { &VALUE_WITNESS_SYM(Bo) } }, { { &destroyTestObject }, { &VALUE_WITNESS_SYM(Bo) } },
{ { { MetadataKind::Class } }, 0, SWIFT_CLASS_IS_SWIFT_MASK, { { nullptr }, ClassFlags::UsesSwiftRefcounting, 0, 0, 0, 0, 0, 0 }
ClassFlags::UsesSwiftRefcounting, 0, 0, 0, 0, 0, 0 }
}; };
/// Create an object that, when deallocated, stores the given value to /// Create an object that, when deallocated, stores the given value to

View File

@@ -98,8 +98,7 @@ static SWIFT_CC(swift) void deinitTestObject(SWIFT_CONTEXT HeapObject *_object)
static const FullMetadata<ClassMetadata> TestClassObjectMetadata = { static const FullMetadata<ClassMetadata> TestClassObjectMetadata = {
{ { &deinitTestObject }, { &VALUE_WITNESS_SYM(Bo) } }, { { &deinitTestObject }, { &VALUE_WITNESS_SYM(Bo) } },
{ { { MetadataKind::Class } }, 0, SWIFT_CLASS_IS_SWIFT_MASK, { { nullptr }, ClassFlags::UsesSwiftRefcounting, 0, 0, 0, 0, 0, 0 }
ClassFlags::UsesSwiftRefcounting, 0, 0, 0, 0, 0, 0 }
}; };
/// Create an object that, when deinited, stores the given value to /// Create an object that, when deinited, stores the given value to

View File

@@ -252,8 +252,7 @@ TEST(Concurrent, ConcurrentMap) {
FullMetadata<ClassMetadata> MetadataTest2 = { FullMetadata<ClassMetadata> MetadataTest2 = {
{ { nullptr }, { &VALUE_WITNESS_SYM(Bo) } }, { { nullptr }, { &VALUE_WITNESS_SYM(Bo) } },
{ { { MetadataKind::Class } }, nullptr, /*rodata*/ 1, { { nullptr }, ClassFlags(), 0, 0, 0, 0, 0, 0 }
ClassFlags(), 0, 0, 0, 0, 0, 0 }
}; };
TEST(MetadataTest, getMetatypeMetadata) { TEST(MetadataTest, getMetatypeMetadata) {

View File

@@ -31,8 +31,7 @@ static SWIFT_CC(swift) void destroyTestObject(SWIFT_CONTEXT HeapObject *_object)
static const FullMetadata<ClassMetadata> TestClassObjectMetadata = { static const FullMetadata<ClassMetadata> TestClassObjectMetadata = {
{ { &destroyTestObject }, { &VALUE_WITNESS_SYM(Bo) } }, { { &destroyTestObject }, { &VALUE_WITNESS_SYM(Bo) } },
{ { { MetadataKind::Class } }, 0, SWIFT_CLASS_IS_SWIFT_MASK, { { nullptr }, ClassFlags::UsesSwiftRefcounting, 0, 0, 0, 0, 0, 0 }
ClassFlags::UsesSwiftRefcounting, 0, 0, 0, 0, 0, 0 }
}; };
/// Create an object that, when deallocated, stores the given value to /// Create an object that, when deallocated, stores the given value to