@@ -1814,13 +1814,10 @@ class MetadataReader {
18141814 if (!type->hasResilientSuperclass ())
18151815 return type->getNonResilientGenericArgumentOffset ();
18161816
1817- auto bounds = readMetadataBoundsOfSuperclass (descriptor);
1817+ auto bounds = computeMetadataBoundsFromSuperclass (descriptor);
18181818 if (!bounds)
18191819 return std::nullopt ;
18201820
1821- bounds->adjustForSubclass (type->areImmediateMembersNegative (),
1822- type->NumImmediateMembers );
1823-
18241821 return bounds->ImmediateMembersOffset / sizeof (StoredPointer);
18251822 }
18261823
@@ -1841,39 +1838,72 @@ class MetadataReader {
18411838
18421839 using ClassMetadataBounds = TargetClassMetadataBounds<Runtime>;
18431840
1844- // This follows computeMetadataBoundsForSuperclass .
1841+ // This follows getMetadataBounds in ABI/Metadata.h .
18451842 std::optional<ClassMetadataBounds>
1846- readMetadataBoundsOfSuperclass (ContextDescriptorRef subclassRef) {
1847- auto subclass = cast<TargetClassDescriptor<Runtime>>(subclassRef);
1848- if (!subclass->hasResilientSuperclass ())
1849- return ClassMetadataBounds::forSwiftRootClass ();
1843+ getClassMetadataBounds (ContextDescriptorRef classRef) {
1844+ auto classDescriptor = cast<TargetClassDescriptor<Runtime>>(classRef);
1845+
1846+ if (!classDescriptor->hasResilientSuperclass ()) {
1847+ auto nonResilientImmediateMembersOffset =
1848+ classDescriptor->areImmediateMembersNegative ()
1849+ ? -int32_t (classDescriptor->MetadataNegativeSizeInWords )
1850+ : int32_t (classDescriptor->MetadataPositiveSizeInWords -
1851+ classDescriptor->NumImmediateMembers );
1852+ typename Runtime::StoredPointerDifference immediateMembersOffset =
1853+ nonResilientImmediateMembersOffset * sizeof (StoredPointer);
18501854
1851- auto rawSuperclass =
1852- resolveRelativeField (subclassRef, subclass-> getResilientSuperclass ());
1853- if (!rawSuperclass) {
1854- return ClassMetadataBounds::forSwiftRootClass () ;
1855+ ClassMetadataBounds bounds{immediateMembersOffset,
1856+ classDescriptor-> MetadataNegativeSizeInWords ,
1857+ classDescriptor-> MetadataPositiveSizeInWords };
1858+ return bounds ;
18551859 }
18561860
1857- return forTypeReference<ClassMetadataBounds>(
1858- subclass->getResilientSuperclassReferenceKind (), rawSuperclass,
1859- [&](ContextDescriptorRef superclass)
1860- -> std::optional<ClassMetadataBounds> {
1861- if (!isa<TargetClassDescriptor<Runtime>>(superclass))
1862- return std::nullopt ;
1863- return readMetadataBoundsOfSuperclass (superclass);
1864- },
1865- [&](MetadataRef metadata) -> std::optional<ClassMetadataBounds> {
1866- auto cls = dyn_cast<TargetClassMetadata>(metadata);
1867- if (!cls)
1868- return std::nullopt ;
1861+ return computeMetadataBoundsFromSuperclass (classRef);
1862+ }
18691863
1870- return cls->getClassBoundsAsSwiftSuperclass ();
1871- },
1872- [](StoredPointer objcClassName) -> std::optional<ClassMetadataBounds> {
1873- // We have no ability to look up an ObjC class by name.
1874- // FIXME: add a query for this; clients may have a way to do it.
1875- return std::nullopt ;
1876- });
1864+ // This follows computeMetadataBoundsFromSuperclass in Metadata.cpp.
1865+ std::optional<ClassMetadataBounds>
1866+ computeMetadataBoundsFromSuperclass (ContextDescriptorRef subclassRef) {
1867+ auto subclass = cast<TargetClassDescriptor<Runtime>>(subclassRef);
1868+ std::optional<ClassMetadataBounds> bounds;
1869+
1870+ if (!subclass->hasResilientSuperclass ()) {
1871+ bounds = ClassMetadataBounds::forSwiftRootClass ();
1872+ } else {
1873+ auto rawSuperclass =
1874+ resolveRelativeField (subclassRef, subclass->getResilientSuperclass ());
1875+ if (!rawSuperclass) {
1876+ return std::nullopt ;
1877+ }
1878+
1879+ bounds = forTypeReference<ClassMetadataBounds>(
1880+ subclass->getResilientSuperclassReferenceKind (), rawSuperclass,
1881+ [&](ContextDescriptorRef superclass)
1882+ -> std::optional<ClassMetadataBounds> {
1883+ if (!isa<TargetClassDescriptor<Runtime>>(superclass))
1884+ return std::nullopt ;
1885+ return getClassMetadataBounds (superclass);
1886+ },
1887+ [&](MetadataRef metadata) -> std::optional<ClassMetadataBounds> {
1888+ auto cls = dyn_cast<TargetClassMetadata>(metadata);
1889+ if (!cls)
1890+ return std::nullopt ;
1891+
1892+ return cls->getClassBoundsAsSwiftSuperclass ();
1893+ },
1894+ [](StoredPointer objcClassName)
1895+ -> std::optional<ClassMetadataBounds> {
1896+ // We have no ability to look up an ObjC class by name.
1897+ // FIXME: add a query for this; clients may have a way to do it.
1898+ return std::nullopt ;
1899+ });
1900+ }
1901+ if (!bounds) {
1902+ return std::nullopt ;
1903+ }
1904+ bounds->adjustForSubclass (subclass->areImmediateMembersNegative (),
1905+ subclass->NumImmediateMembers );
1906+ return bounds;
18771907 }
18781908
18791909 template <class Result , class DescriptorFn , class MetadataFn ,
@@ -1885,11 +1915,12 @@ class MetadataReader {
18851915 const ClassNameFn &classNameFn) {
18861916 switch (refKind) {
18871917 case TypeReferenceKind::IndirectTypeDescriptor: {
1888- StoredPointer descriptorAddress = 0 ;
1889- if (!Reader->readInteger (RemoteAddress (ref), &descriptorAddress))
1918+ StoredSignedPointer descriptorAddress;
1919+ if (!Reader->readInteger (RemoteAddress (ref), &descriptorAddress)) {
18901920 return std::nullopt ;
1921+ }
18911922
1892- ref = descriptorAddress;
1923+ ref = stripSignedPointer ( descriptorAddress) ;
18931924 LLVM_FALLTHROUGH;
18941925 }
18951926
0 commit comments