From 55533a94b9d327c0bc4090f92ddb789b35a4249d Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 3 Jun 2025 15:16:05 -0700 Subject: [PATCH 1/4] IRGen: Emit objc type encoding for ivars --- lib/IRGen/GenClass.cpp | 8 +++++++- lib/IRGen/GenObjC.cpp | 7 +++++++ lib/IRGen/GenObjC.h | 3 +++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp index 1b7f1356eac76..18140632ffe84 100644 --- a/lib/IRGen/GenClass.cpp +++ b/lib/IRGen/GenClass.cpp @@ -2052,6 +2052,7 @@ namespace { // Otherwise, we should have a normal stored property. auto ivar = field.getVarDecl(); + // If the field offset is fixed relative to the start of the superclass, // reference the global from the ivar metadata so that the Objective-C // runtime will slide it down. @@ -2067,6 +2068,11 @@ namespace { } StringRef name = field.getName(); + std::string typeEnc; + if (field.getKind() == Field::Var && + requiresObjCPropertyDescriptor(IGM, field.getVarDecl())) { + getObjCEncodingForType(IGM, field.getVarDecl(), typeEnc); + } const TypeInfo &storageTI = pair.second.getType(); auto fields = ivars.beginStruct(); @@ -2079,7 +2085,7 @@ namespace { fields.add(IGM.getAddrOfGlobalString(name)); // TODO: clang puts this in __TEXT,__objc_methtype,cstring_literals - fields.add(IGM.getAddrOfGlobalString("")); + fields.add(IGM.getAddrOfGlobalString(typeEnc)); Size size; Alignment alignment; diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp index 0dd45be382692..96cc0a33c4603 100644 --- a/lib/IRGen/GenObjC.cpp +++ b/lib/IRGen/GenObjC.cpp @@ -1258,6 +1258,13 @@ static clang::CanQualType getObjCPropertyType(IRGenModule &IGM, methodTy->getFormalCSemanticResult(IGM.getSILModule()).getASTType()); } +void irgen::getObjCEncodingForType(IRGenModule &IGM, VarDecl *property, + std::string &s) { + auto t = getObjCPropertyType(IGM, property); + if (t) + IGM.getClangASTContext().getObjCEncodingForType(t, s); +} + void irgen::getObjCEncodingForPropertyType(IRGenModule &IGM, VarDecl *property, std::string &s) { // FIXME: Property encoding differs in slight ways that aren't publicly diff --git a/lib/IRGen/GenObjC.h b/lib/IRGen/GenObjC.h index 386b2e7aa8b43..f4cc6800bb77d 100644 --- a/lib/IRGen/GenObjC.h +++ b/lib/IRGen/GenObjC.h @@ -170,6 +170,9 @@ namespace irgen { llvm::Function *impl, bool isDestroyer); + /// Get the type encoding for an ObjC ivar. + void getObjCEncodingForType(IRGenModule &IGM, VarDecl *property, std::string &s); + /// Get the type encoding for an ObjC property. void getObjCEncodingForPropertyType(IRGenModule &IGM, VarDecl *property, std::string &s); From cc3206e6ad2d2ff5c0b91fc73781456c2b538822 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 4 Jun 2025 11:21:48 -0700 Subject: [PATCH 2/4] Update tests --- lib/IRGen/GenClass.cpp | 1 - lib/IRGen/GenObjC.cpp | 3 +-- test/IRGen/objc_implementation.swift | 6 +++--- test/IRGen/objc_subclass.swift | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp index 18140632ffe84..429af3988b336 100644 --- a/lib/IRGen/GenClass.cpp +++ b/lib/IRGen/GenClass.cpp @@ -2052,7 +2052,6 @@ namespace { // Otherwise, we should have a normal stored property. auto ivar = field.getVarDecl(); - // If the field offset is fixed relative to the start of the superclass, // reference the global from the ivar metadata so that the Objective-C // runtime will slide it down. diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp index 96cc0a33c4603..08443109f11f9 100644 --- a/lib/IRGen/GenObjC.cpp +++ b/lib/IRGen/GenObjC.cpp @@ -1260,8 +1260,7 @@ static clang::CanQualType getObjCPropertyType(IRGenModule &IGM, void irgen::getObjCEncodingForType(IRGenModule &IGM, VarDecl *property, std::string &s) { - auto t = getObjCPropertyType(IGM, property); - if (t) + if (auto t = getObjCPropertyType(IGM, property)) IGM.getClangASTContext().getObjCEncodingForType(t, s); } diff --git a/test/IRGen/objc_implementation.swift b/test/IRGen/objc_implementation.swift index 844ef699cbc0d..5905b7a8f9bb6 100644 --- a/test/IRGen/objc_implementation.swift +++ b/test/IRGen/objc_implementation.swift @@ -35,7 +35,7 @@ // CHECK-SAME: { ptr, ptr, ptr } { ptr @"\01L_selector_data(mutableCopyWithZone:)", ptr @".str.11.@24@0:8^v16", ptr @"$sSo9ImplClassC19objc_implementationE11mutableCopy4withypSg10ObjectiveC6NSZoneVSg_tFTo{{(\.ptrauth)?}}" } // CHECK-SAME: { ptr, ptr, ptr } { ptr @"\01L_selector_data(dealloc)", ptr @".str.7.v16@0:8", ptr @"$sSo9ImplClassC19objc_implementationEfDTo{{(\.ptrauth)?}}" }, { ptr, ptr, ptr } { ptr [[selector_data__cxx_destruct]], ptr @".str.7.v16@0:8", ptr @"$sSo9ImplClassCfETo{{(\.ptrauth)?}}" } // CHECK-LABEL: @_IVARS_ImplClass = internal constant { i32, i32, [2 x { ptr, ptr, ptr, i32, i32 }] } { i32 32, i32 2, [2 x { ptr, ptr, ptr, i32, i32 }] [ -// CHECK-SAME: { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo9ImplClassC19objc_implementationE12implPropertys5Int32VvpWvd", ptr @.str.12.implProperty, ptr @.str.0., i32 2, i32 4 } +// CHECK-SAME: { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo9ImplClassC19objc_implementationE12implPropertys5Int32VvpWvd", ptr @.str.12.implProperty, ptr @.str.1.i, i32 2, i32 4 } // CHECK-SAME: { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo9ImplClassC19objc_implementationE13implProperty2So8NSObjectCSgvpWvd", ptr @.str.13.implProperty2, ptr @.str.0., i32 3, i32 8 } // CHECK-LABEL: @_PROPERTIES_ImplClass = internal constant { i32, i32, [1 x { ptr, ptr }] } { i32 16, i32 1, [1 x { ptr, ptr }] [ // CHECK-SAME: { ptr, ptr } { ptr @.str.12.implProperty, ptr @".str.18.Ti,N,VimplProperty" } @@ -103,7 +103,7 @@ // CHECK: @"OBJC_METACLASS_$_NoInitImplClass" = global %objc_class { ptr @"OBJC_METACLASS_$_NSObject", ptr @"OBJC_METACLASS_$_NSObject", ptr @_objc_empty_cache, ptr null, i64 ptrtoint (ptr @_METACLASS_DATA_NoInitImplClass to i64) }, align 8 // CHECK: @_METACLASS_DATA_NoInitImplClass = internal constant { i32, i32, i32, i32, ptr, ptr, ptr, ptr, ptr, ptr, ptr } { i32 129, i32 40, i32 40, i32 0, ptr null, ptr @.str.15.NoInitImplClass, ptr null, ptr null, ptr null, ptr null, ptr null }, section "__DATA, __objc_const", align 8 // CHECK: @_INSTANCE_METHODS_NoInitImplClass = internal constant { i32, i32, [9 x { ptr, ptr, ptr }] } { i32 24, i32 9, [9 x { ptr, ptr, ptr }] [{ ptr, ptr, ptr } { ptr @"\01L_selector_data(s1)", ptr @".str.7.@16@0:8", ptr @"$sSo15NoInitImplClassC19objc_implementationE2s1SSvgTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(s2)", ptr @".str.7.@16@0:8", ptr @"$sSo15NoInitImplClassC19objc_implementationE2s2SSvgTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(setS2:)", ptr @".str.10.v24@0:8@16", ptr @"$sSo15NoInitImplClassC19objc_implementationE2s2SSvsTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(s3)", ptr @".str.7.@16@0:8", ptr @"$sSo15NoInitImplClassC19objc_implementationE2s3SSvgTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(s4)", ptr @".str.7.@16@0:8", ptr @"$sSo15NoInitImplClassC19objc_implementationE2s4SSvgTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(setS4:)", ptr @".str.10.v24@0:8@16", ptr @"$sSo15NoInitImplClassC19objc_implementationE2s4SSvsTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(dealloc)", ptr @".str.7.v16@0:8", ptr @"$sSo15NoInitImplClassC19objc_implementationEfDTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(init)", ptr @".str.7.@16@0:8", ptr @"$sSo15NoInitImplClassC19objc_implementationEABycfcTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(.cxx_destruct)", ptr @".str.7.v16@0:8", ptr @"$sSo15NoInitImplClassCfETo" }] }, section "__DATA, __objc_data", align 8 -// CHECK: @_IVARS_NoInitImplClass = internal constant { i32, i32, [4 x { ptr, ptr, ptr, i32, i32 }] } { i32 32, i32 4, [4 x { ptr, ptr, ptr, i32, i32 }] [{ ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s1SSvpWvd", ptr @.str.2.s1, ptr @.str.0., i32 3, i32 16 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s2SSvpWvd", ptr @.str.2.s2, ptr @.str.0., i32 3, i32 16 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s3SSvpWvd", ptr @.str.2.s3, ptr @.str.0., i32 3, i32 16 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s4SSvpWvd", ptr @.str.2.s4, ptr @.str.0., i32 3, i32 16 }] }, section "__DATA, __objc_const", align 8 +// CHECK: @_IVARS_NoInitImplClass = internal constant { i32, i32, [4 x { ptr, ptr, ptr, i32, i32 }] } { i32 32, i32 4, [4 x { ptr, ptr, ptr, i32, i32 }] [{ ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s1SSvpWvd", ptr @.str.2.s1, ptr @".str.1.@", i32 3, i32 16 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s2SSvpWvd", ptr @.str.2.s2, ptr @".str.1.@", i32 3, i32 16 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s3SSvpWvd", ptr @.str.2.s3, ptr @".str.1.@", i32 3, i32 16 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s4SSvpWvd", ptr @.str.2.s4, ptr @".str.1.@", i32 3, i32 16 }] }, section "__DATA, __objc_const", align 8 // CHECK: @_PROPERTIES_NoInitImplClass = internal constant { i32, i32, [4 x { ptr, ptr }] } { i32 16, i32 4, [4 x { ptr, ptr }] [{ ptr, ptr } { ptr @.str.2.s1, ptr @".str.16.T@\22NSString\22,N,R" }, { ptr, ptr } { ptr @.str.2.s2, ptr @".str.16.T@\22NSString\22,N,C" }, { ptr, ptr } { ptr @.str.2.s3, ptr @".str.16.T@\22NSString\22,N,R" }, { ptr, ptr } { ptr @.str.2.s4, ptr @".str.16.T@\22NSString\22,N,C" }] }, section "__DATA, __objc_const", align 8 // CHECK: @_DATA_NoInitImplClass = internal constant { i32, i32, i32, i32, ptr, ptr, ptr, ptr, ptr, ptr, ptr } { i32 388, i32 8, i32 72, i32 0, ptr null, ptr @.str.15.NoInitImplClass, ptr @_INSTANCE_METHODS_NoInitImplClass, ptr null, ptr @_IVARS_NoInitImplClass, ptr null, ptr @_PROPERTIES_NoInitImplClass }, section "__DATA, __objc_data", align 8 // CHECK: @"OBJC_CLASS_$_NoInitImplClass" = global <{ i64, ptr, ptr, ptr, i64 }> <{ i64 ptrtoint (ptr @"OBJC_METACLASS_$_NoInitImplClass" to i64), ptr @"OBJC_CLASS_$_NSObject", ptr @_objc_empty_cache, ptr null, i64 ptrtoint (ptr @_DATA_NoInitImplClass to i64) }>, section "__DATA,__objc_data, regular", align 8 @@ -153,7 +153,7 @@ open class SwiftSubclass: ImplClass { // TODO: Why the extra i32 field above? // Class -// CHECK: @_IVARS_ImplClassWithResilientStoredProperty = internal constant { i32, i32, [4 x { ptr, ptr, ptr, i32, i32 }] } { i32 32, i32 4, [4 x { ptr, ptr, ptr, i32, i32 }] [{ ptr, ptr, ptr, i32, i32 } { ptr @"$sSo36ImplClassWithResilientStoredPropertyC19objc_implementationE9beforeInts5Int32VvpWvd", ptr @.str.9.beforeInt, ptr @.str.0., i32 2, i32 4 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo36ImplClassWithResilientStoredPropertyC19objc_implementationE6mirrors6MirrorVSgvpWvd", ptr @.str.6.mirror, ptr @.str.0., i32 0, i32 0 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo36ImplClassWithResilientStoredPropertyC19objc_implementationE13afterIntFinals5Int32VvpWvd", ptr @.str.13.afterIntFinal, ptr @.str.0., i32 2, i32 4 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo36ImplClassWithResilientStoredPropertyC19objc_implementationE8afterInts5Int32VvpWvd", ptr @.str.8.afterInt, ptr @.str.0., i32 2, i32 4 }] }, section "__DATA, __objc_const", align 8 +// CHECK: @_IVARS_ImplClassWithResilientStoredProperty = internal constant { i32, i32, [4 x { ptr, ptr, ptr, i32, i32 }] } { i32 32, i32 4, [4 x { ptr, ptr, ptr, i32, i32 }] [{ ptr, ptr, ptr, i32, i32 } { ptr @"$sSo36ImplClassWithResilientStoredPropertyC19objc_implementationE9beforeInts5Int32VvpWvd", ptr @.str.9.beforeInt, ptr @.str.1.i, i32 2, i32 4 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo36ImplClassWithResilientStoredPropertyC19objc_implementationE6mirrors6MirrorVSgvpWvd", ptr @.str.6.mirror, ptr @.str.0., i32 0, i32 0 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo36ImplClassWithResilientStoredPropertyC19objc_implementationE13afterIntFinals5Int32VvpWvd", ptr @.str.13.afterIntFinal, ptr @.str.0., i32 2, i32 4 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo36ImplClassWithResilientStoredPropertyC19objc_implementationE8afterInts5Int32VvpWvd", ptr @.str.8.afterInt, ptr @.str.1.i, i32 2, i32 4 }] }, section "__DATA, __objc_const", align 8 // CHECK: @_DATA_ImplClassWithResilientStoredProperty = internal constant { i32, i32, i32, i32, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr } { i32 452, i32 8, i32 20, i32 0, ptr null, ptr @.str.36.ImplClassWithResilientStoredProperty, ptr @_INSTANCE_METHODS_ImplClassWithResilientStoredProperty, ptr null, ptr @_IVARS_ImplClassWithResilientStoredProperty, ptr null, ptr @_PROPERTIES_ImplClassWithResilientStoredProperty, ptr @"$sSo36ImplClassWithResilientStoredPropertyCMU" }, section "__DATA, __objc_data", align 8 // CHECK: @"OBJC_CLASS_$_ImplClassWithResilientStoredProperty" = global <{ i64, ptr, ptr, ptr, i64 }> <{ i64 ptrtoint (ptr @"OBJC_METACLASS_$_ImplClassWithResilientStoredProperty" to i64), ptr @"OBJC_CLASS_$_NSObject", ptr @_objc_empty_cache, ptr null, i64 ptrtoint (ptr @_DATA_ImplClassWithResilientStoredProperty to i64) }>, section "__DATA,__objc_data, regular", align 8 diff --git a/test/IRGen/objc_subclass.swift b/test/IRGen/objc_subclass.swift index 5f89ef8a6f26e..8f2329894301a 100644 --- a/test/IRGen/objc_subclass.swift +++ b/test/IRGen/objc_subclass.swift @@ -163,7 +163,7 @@ // CHECK-64: [1 x { ptr, ptr, ptr, i32, i32 }] [{ ptr, ptr, ptr, i32, i32 } { // CHECK-64: ptr @"$s13objc_subclass10SwiftGizmoC1xSivpWvd", // CHECK-64: ptr @.str.1.x, -// CHECK-64: ptr @.str.0., +// CHECK-64: ptr @.str.1.q, // CHECK-64: i32 3, // CHECK-64: i32 8 }] // CHECK-64: }, section "__DATA, {{.*}}", align 8 From 2ddbb6b52c5ee06bbb207e07aea039a0b9280045 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 4 Jun 2025 13:06:25 -0700 Subject: [PATCH 3/4] Update to match objc ivar type encoding --- lib/IRGen/GenClass.cpp | 8 ++++---- lib/IRGen/GenObjC.cpp | 6 ------ lib/IRGen/GenObjC.h | 3 --- test/IRGen/objc_implementation.swift | 2 +- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp index 429af3988b336..a80e7080ea0dd 100644 --- a/lib/IRGen/GenClass.cpp +++ b/lib/IRGen/GenClass.cpp @@ -2068,10 +2068,10 @@ namespace { StringRef name = field.getName(); std::string typeEnc; - if (field.getKind() == Field::Var && - requiresObjCPropertyDescriptor(IGM, field.getVarDecl())) { - getObjCEncodingForType(IGM, field.getVarDecl(), typeEnc); - } + auto *varDecl = field.getVarDecl(); + if (field.getKind() == Field::Var && varDecl->isObjC() && + varDecl->hasStorage()) + getObjCEncodingForPropertyType(IGM, varDecl, typeEnc); const TypeInfo &storageTI = pair.second.getType(); auto fields = ivars.beginStruct(); diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp index 08443109f11f9..0dd45be382692 100644 --- a/lib/IRGen/GenObjC.cpp +++ b/lib/IRGen/GenObjC.cpp @@ -1258,12 +1258,6 @@ static clang::CanQualType getObjCPropertyType(IRGenModule &IGM, methodTy->getFormalCSemanticResult(IGM.getSILModule()).getASTType()); } -void irgen::getObjCEncodingForType(IRGenModule &IGM, VarDecl *property, - std::string &s) { - if (auto t = getObjCPropertyType(IGM, property)) - IGM.getClangASTContext().getObjCEncodingForType(t, s); -} - void irgen::getObjCEncodingForPropertyType(IRGenModule &IGM, VarDecl *property, std::string &s) { // FIXME: Property encoding differs in slight ways that aren't publicly diff --git a/lib/IRGen/GenObjC.h b/lib/IRGen/GenObjC.h index f4cc6800bb77d..386b2e7aa8b43 100644 --- a/lib/IRGen/GenObjC.h +++ b/lib/IRGen/GenObjC.h @@ -170,9 +170,6 @@ namespace irgen { llvm::Function *impl, bool isDestroyer); - /// Get the type encoding for an ObjC ivar. - void getObjCEncodingForType(IRGenModule &IGM, VarDecl *property, std::string &s); - /// Get the type encoding for an ObjC property. void getObjCEncodingForPropertyType(IRGenModule &IGM, VarDecl *property, std::string &s); diff --git a/test/IRGen/objc_implementation.swift b/test/IRGen/objc_implementation.swift index 5905b7a8f9bb6..eb181328f3522 100644 --- a/test/IRGen/objc_implementation.swift +++ b/test/IRGen/objc_implementation.swift @@ -103,7 +103,7 @@ // CHECK: @"OBJC_METACLASS_$_NoInitImplClass" = global %objc_class { ptr @"OBJC_METACLASS_$_NSObject", ptr @"OBJC_METACLASS_$_NSObject", ptr @_objc_empty_cache, ptr null, i64 ptrtoint (ptr @_METACLASS_DATA_NoInitImplClass to i64) }, align 8 // CHECK: @_METACLASS_DATA_NoInitImplClass = internal constant { i32, i32, i32, i32, ptr, ptr, ptr, ptr, ptr, ptr, ptr } { i32 129, i32 40, i32 40, i32 0, ptr null, ptr @.str.15.NoInitImplClass, ptr null, ptr null, ptr null, ptr null, ptr null }, section "__DATA, __objc_const", align 8 // CHECK: @_INSTANCE_METHODS_NoInitImplClass = internal constant { i32, i32, [9 x { ptr, ptr, ptr }] } { i32 24, i32 9, [9 x { ptr, ptr, ptr }] [{ ptr, ptr, ptr } { ptr @"\01L_selector_data(s1)", ptr @".str.7.@16@0:8", ptr @"$sSo15NoInitImplClassC19objc_implementationE2s1SSvgTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(s2)", ptr @".str.7.@16@0:8", ptr @"$sSo15NoInitImplClassC19objc_implementationE2s2SSvgTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(setS2:)", ptr @".str.10.v24@0:8@16", ptr @"$sSo15NoInitImplClassC19objc_implementationE2s2SSvsTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(s3)", ptr @".str.7.@16@0:8", ptr @"$sSo15NoInitImplClassC19objc_implementationE2s3SSvgTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(s4)", ptr @".str.7.@16@0:8", ptr @"$sSo15NoInitImplClassC19objc_implementationE2s4SSvgTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(setS4:)", ptr @".str.10.v24@0:8@16", ptr @"$sSo15NoInitImplClassC19objc_implementationE2s4SSvsTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(dealloc)", ptr @".str.7.v16@0:8", ptr @"$sSo15NoInitImplClassC19objc_implementationEfDTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(init)", ptr @".str.7.@16@0:8", ptr @"$sSo15NoInitImplClassC19objc_implementationEABycfcTo" }, { ptr, ptr, ptr } { ptr @"\01L_selector_data(.cxx_destruct)", ptr @".str.7.v16@0:8", ptr @"$sSo15NoInitImplClassCfETo" }] }, section "__DATA, __objc_data", align 8 -// CHECK: @_IVARS_NoInitImplClass = internal constant { i32, i32, [4 x { ptr, ptr, ptr, i32, i32 }] } { i32 32, i32 4, [4 x { ptr, ptr, ptr, i32, i32 }] [{ ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s1SSvpWvd", ptr @.str.2.s1, ptr @".str.1.@", i32 3, i32 16 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s2SSvpWvd", ptr @.str.2.s2, ptr @".str.1.@", i32 3, i32 16 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s3SSvpWvd", ptr @.str.2.s3, ptr @".str.1.@", i32 3, i32 16 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s4SSvpWvd", ptr @.str.2.s4, ptr @".str.1.@", i32 3, i32 16 }] }, section "__DATA, __objc_const", align 8 +// CHECK: @_IVARS_NoInitImplClass = internal constant { i32, i32, [4 x { ptr, ptr, ptr, i32, i32 }] } { i32 32, i32 4, [4 x { ptr, ptr, ptr, i32, i32 }] [{ ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s1SSvpWvd", ptr @.str.2.s1, ptr @".str.11.@\22NSString\22", i32 3, i32 16 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s2SSvpWvd", ptr @.str.2.s2, ptr @".str.11.@\22NSString\22", i32 3, i32 16 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s3SSvpWvd", ptr @.str.2.s3, ptr @".str.11.@\22NSString\22", i32 3, i32 16 }, { ptr, ptr, ptr, i32, i32 } { ptr @"$sSo15NoInitImplClassC19objc_implementationE2s4SSvpWvd", ptr @.str.2.s4, ptr @".str.11.@\22NSString\22", i32 3, i32 16 }] }, section "__DATA, __objc_const", align 8 // CHECK: @_PROPERTIES_NoInitImplClass = internal constant { i32, i32, [4 x { ptr, ptr }] } { i32 16, i32 4, [4 x { ptr, ptr }] [{ ptr, ptr } { ptr @.str.2.s1, ptr @".str.16.T@\22NSString\22,N,R" }, { ptr, ptr } { ptr @.str.2.s2, ptr @".str.16.T@\22NSString\22,N,C" }, { ptr, ptr } { ptr @.str.2.s3, ptr @".str.16.T@\22NSString\22,N,R" }, { ptr, ptr } { ptr @.str.2.s4, ptr @".str.16.T@\22NSString\22,N,C" }] }, section "__DATA, __objc_const", align 8 // CHECK: @_DATA_NoInitImplClass = internal constant { i32, i32, i32, i32, ptr, ptr, ptr, ptr, ptr, ptr, ptr } { i32 388, i32 8, i32 72, i32 0, ptr null, ptr @.str.15.NoInitImplClass, ptr @_INSTANCE_METHODS_NoInitImplClass, ptr null, ptr @_IVARS_NoInitImplClass, ptr null, ptr @_PROPERTIES_NoInitImplClass }, section "__DATA, __objc_data", align 8 // CHECK: @"OBJC_CLASS_$_NoInitImplClass" = global <{ i64, ptr, ptr, ptr, i64 }> <{ i64 ptrtoint (ptr @"OBJC_METACLASS_$_NoInitImplClass" to i64), ptr @"OBJC_CLASS_$_NSObject", ptr @_objc_empty_cache, ptr null, i64 ptrtoint (ptr @_DATA_NoInitImplClass to i64) }>, section "__DATA,__objc_data, regular", align 8 From d77fe2bb1da62269224da4471b060d89ceed9f1a Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Thu, 5 Jun 2025 10:54:50 -0700 Subject: [PATCH 4/4] Only call getVarDecl when kind is Field::Var --- lib/IRGen/GenClass.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp index a80e7080ea0dd..ae2c9e61310d6 100644 --- a/lib/IRGen/GenClass.cpp +++ b/lib/IRGen/GenClass.cpp @@ -2068,10 +2068,11 @@ namespace { StringRef name = field.getName(); std::string typeEnc; - auto *varDecl = field.getVarDecl(); - if (field.getKind() == Field::Var && varDecl->isObjC() && - varDecl->hasStorage()) - getObjCEncodingForPropertyType(IGM, varDecl, typeEnc); + if (field.getKind() == Field::Var) { + auto *varDecl = field.getVarDecl(); + if (varDecl->isObjC() && varDecl->hasStorage()) + getObjCEncodingForPropertyType(IGM, varDecl, typeEnc); + } const TypeInfo &storageTI = pair.second.getType(); auto fields = ivars.beginStruct();