about summary refs log tree commit diff
path: root/tests/codegen-llvm
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-09-17 14:56:44 +1000
committerGitHub <noreply@github.com>2025-09-17 14:56:44 +1000
commit6ad98750e0d2261aa123806c69a133b2fbd18d88 (patch)
tree53152bd7a544941557844f85b18cc1a1ba9ee527 /tests/codegen-llvm
parentf21a9c94cf39cdb26a15ea0967501629f3156958 (diff)
parent1ebf69d1b1a94e99c01680514571c41d0b864c15 (diff)
downloadrust-6ad98750e0d2261aa123806c69a133b2fbd18d88.tar.gz
rust-6ad98750e0d2261aa123806c69a133b2fbd18d88.zip
Rollup merge of #145660 - jbatez:darwin_objc, r=jdonszelmann,madsmtm,tmandry
initial implementation of the darwin_objc unstable feature

Tracking issue: https://github.com/rust-lang/rust/issues/145496

This feature makes it possible to reference Objective-C classes and selectors using the same ABI used by native Objective-C on Apple/Darwin platforms. Without it, Rust code interacting with Objective-C must resort to loading classes and selectors using costly string-based lookups at runtime. With it, these references can be loaded efficiently at dynamic load time.

r? ```@tmandry```

try-job: `*apple*`
try-job: `x86_64-gnu-nopt`
Diffstat (limited to 'tests/codegen-llvm')
-rw-r--r--tests/codegen-llvm/auxiliary/darwin_objc_aux.rs27
-rw-r--r--tests/codegen-llvm/darwin-no-objc.rs52
-rw-r--r--tests/codegen-llvm/darwin-objc-abi-v1.rs100
-rw-r--r--tests/codegen-llvm/darwin-objc-abi-v2.rs185
-rw-r--r--tests/codegen-llvm/darwin-objc-cross-crate.rs58
5 files changed, 422 insertions, 0 deletions
diff --git a/tests/codegen-llvm/auxiliary/darwin_objc_aux.rs b/tests/codegen-llvm/auxiliary/darwin_objc_aux.rs
new file mode 100644
index 00000000000..3c35d003c8a
--- /dev/null
+++ b/tests/codegen-llvm/auxiliary/darwin_objc_aux.rs
@@ -0,0 +1,27 @@
+#![crate_type = "lib"]
+#![feature(darwin_objc)]
+
+use std::os::darwin::objc;
+
+#[link(name = "Foundation", kind = "framework")]
+unsafe extern "C" {}
+
+#[inline(always)]
+pub fn inline_get_object_class() -> objc::Class {
+    objc::class!("NSObject")
+}
+
+#[inline(always)]
+pub fn inline_get_alloc_selector() -> objc::SEL {
+    objc::selector!("alloc")
+}
+
+#[inline(never)]
+pub fn never_inline_get_string_class() -> objc::Class {
+    objc::class!("NSString")
+}
+
+#[inline(never)]
+pub fn never_inline_get_init_selector() -> objc::SEL {
+    objc::selector!("init")
+}
diff --git a/tests/codegen-llvm/darwin-no-objc.rs b/tests/codegen-llvm/darwin-no-objc.rs
new file mode 100644
index 00000000000..fda3671fb6d
--- /dev/null
+++ b/tests/codegen-llvm/darwin-no-objc.rs
@@ -0,0 +1,52 @@
+// Test that we don't generate Objective-C definitions or image info unnecessarily.
+
+//@ add-core-stubs
+//@ revisions: i686_apple_darwin
+//@ [i686_apple_darwin] compile-flags: --target i686-apple-darwin
+//@ [i686_apple_darwin] needs-llvm-components: x86
+//@ revisions: x86_64_macos
+//@ [x86_64_macos] compile-flags: --target x86_64-apple-darwin
+//@ [x86_64_macos] needs-llvm-components: x86
+//@ revisions: aarch64_macos
+//@ [aarch64_macos] compile-flags: --target aarch64-apple-darwin
+//@ [aarch64_macos] needs-llvm-components: aarch64
+//@ revisions: i386_ios
+//@ [i386_ios] compile-flags: --target i386-apple-ios
+//@ [i386_ios] needs-llvm-components: x86
+//@ revisions: x86_64_ios
+//@ [x86_64_ios] compile-flags: --target x86_64-apple-ios
+//@ [x86_64_ios] needs-llvm-components: x86
+//@ revisions: armv7s_ios
+//@ [armv7s_ios] compile-flags: --target armv7s-apple-ios
+//@ [armv7s_ios] needs-llvm-components: arm
+//@ revisions: aarch64_ios
+//@ [aarch64_ios] compile-flags: --target aarch64-apple-ios
+//@ [aarch64_ios] needs-llvm-components: aarch64
+//@ revisions: aarch64_ios_sim
+//@ [aarch64_ios_sim] compile-flags: --target aarch64-apple-ios-sim
+//@ [aarch64_ios_sim] needs-llvm-components: aarch64
+
+#![crate_type = "lib"]
+#![feature(no_core, lang_items)]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+#[no_mangle]
+pub fn foo() {}
+
+// CHECK-NOT: %struct._class_t
+// CHECK-NOT: %struct._objc_module
+// CHECK-NOT: @OBJC_CLASS_NAME_
+// CHECK-NOT: @"OBJC_CLASS_$_{{[0-9A-Z_a-z]+}}"
+// CHECK-NOT: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}"
+// CHECK-NOT: @OBJC_METH_VAR_NAME_
+// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_
+// CHECK-NOT: @OBJC_MODULES
+
+// CHECK-NOT: !"Objective-C Version"
+// CHECK-NOT: !"Objective-C Image Info Version"
+// CHECK-NOT: !"Objective-C Image Info Section"
+// CHECK-NOT: !"Objective-C Is Simulated"
+// CHECK-NOT: !"Objective-C Class Properties"
diff --git a/tests/codegen-llvm/darwin-objc-abi-v1.rs b/tests/codegen-llvm/darwin-objc-abi-v1.rs
new file mode 100644
index 00000000000..0fc1de9332a
--- /dev/null
+++ b/tests/codegen-llvm/darwin-objc-abi-v1.rs
@@ -0,0 +1,100 @@
+// ignore-tidy-linelength
+//@ add-core-stubs
+//@ revisions: i686_apple_darwin
+//@ [i686_apple_darwin] compile-flags: --target i686-apple-darwin
+//@ [i686_apple_darwin] needs-llvm-components: x86
+
+#![crate_type = "lib"]
+#![feature(no_core, lang_items, rustc_attrs)]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+#[no_mangle]
+pub fn get_class() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_class = "MyClass"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_class_again() -> *mut () {
+    // Codegen should de-duplicate this class with the one from get_class above.
+    unsafe extern "C" {
+        #[rustc_objc_class = "MyClass"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_selector() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_selector = "myMethod"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_selector_again() -> *mut () {
+    // Codegen should de-duplicate this selector with the one from get_selector above.
+    unsafe extern "C" {
+        #[rustc_objc_selector = "myMethod"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_other_class() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_class = "OtherClass"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_other_selector() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_selector = "otherMethod"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+// CHECK: %struct._objc_module = type { i32, i32, ptr, ptr }
+
+// CHECK: @OBJC_CLASS_NAME_.{{[0-9]+}} = private unnamed_addr constant [8 x i8] c"MyClass\00", section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @OBJC_CLASS_REFERENCES_.{{[0-9]+}} = private global ptr @OBJC_CLASS_NAME_.{{[0-9]+}}, section "__OBJC,__cls_refs,literal_pointers,no_dead_strip", align 4
+// CHECK-NOT: @OBJC_CLASS_NAME_
+// CHECK-NOT: @OBJC_CLASS_REFERENCES_
+
+// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [9 x i8] c"myMethod\00", section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = private externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4
+// CHECK-NOT: @OBJC_METH_VAR_NAME_
+// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_
+
+// CHECK: @OBJC_CLASS_NAME_.{{[0-9]+}} = private unnamed_addr constant [11 x i8] c"OtherClass\00", section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @OBJC_CLASS_REFERENCES_.{{[0-9]+}} = private global ptr @OBJC_CLASS_NAME_.{{[0-9]+}}, section "__OBJC,__cls_refs,literal_pointers,no_dead_strip", align 4
+
+// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [12 x i8] c"otherMethod\00", section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = private externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4
+
+// CHECK: @OBJC_CLASS_NAME_.{{[0-9]+}} = private unnamed_addr constant [1 x i8] zeroinitializer, section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @OBJC_MODULES = private global %struct._objc_module { i32 7, i32 16, ptr @OBJC_CLASS_NAME_.{{[0-9]+}}, ptr null }, section "__OBJC,__module_info,regular,no_dead_strip", align 4
+
+// CHECK: load ptr, ptr @OBJC_CLASS_REFERENCES_.{{[0-9]+}}, align 4
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, align 4
+// CHECK: load ptr, ptr @OBJC_CLASS_REFERENCES_.{{[0-9]+}}, align 4
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, align 4
+
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 1}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__OBJC,__image_info,regular"}
+// CHECK-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Class Properties", i32 64}
diff --git a/tests/codegen-llvm/darwin-objc-abi-v2.rs b/tests/codegen-llvm/darwin-objc-abi-v2.rs
new file mode 100644
index 00000000000..f142371d582
--- /dev/null
+++ b/tests/codegen-llvm/darwin-objc-abi-v2.rs
@@ -0,0 +1,185 @@
+// ignore-tidy-linelength
+//@ add-core-stubs
+//@ revisions: x86_64_macos
+//@ [x86_64_macos] compile-flags: --target x86_64-apple-darwin
+//@ [x86_64_macos] needs-llvm-components: x86
+//@ revisions: aarch64_macos
+//@ [aarch64_macos] compile-flags: --target aarch64-apple-darwin
+//@ [aarch64_macos] needs-llvm-components: aarch64
+//@ revisions: i386_ios
+//@ [i386_ios] compile-flags: --target i386-apple-ios
+//@ [i386_ios] needs-llvm-components: x86
+//@ revisions: x86_64_ios
+//@ [x86_64_ios] compile-flags: --target x86_64-apple-ios
+//@ [x86_64_ios] needs-llvm-components: x86
+//@ revisions: armv7s_ios
+//@ [armv7s_ios] compile-flags: --target armv7s-apple-ios
+//@ [armv7s_ios] needs-llvm-components: arm
+//@ revisions: aarch64_ios
+//@ [aarch64_ios] compile-flags: --target aarch64-apple-ios
+//@ [aarch64_ios] needs-llvm-components: aarch64
+//@ revisions: aarch64_ios_sim
+//@ [aarch64_ios_sim] compile-flags: --target aarch64-apple-ios-sim
+//@ [aarch64_ios_sim] needs-llvm-components: aarch64
+
+#![crate_type = "lib"]
+#![feature(no_core, lang_items, rustc_attrs)]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+#[no_mangle]
+pub fn get_class() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_class = "MyClass"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_class_again() -> *mut () {
+    // Codegen should de-duplicate this class with the one from get_class above.
+    unsafe extern "C" {
+        #[rustc_objc_class = "MyClass"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_selector() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_selector = "myMethod"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_selector_again() -> *mut () {
+    // Codegen should de-duplicate this selector with the one from get_selector above.
+    unsafe extern "C" {
+        #[rustc_objc_selector = "myMethod"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_other_class() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_class = "OtherClass"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+#[no_mangle]
+pub fn get_other_selector() -> *mut () {
+    unsafe extern "C" {
+        #[rustc_objc_selector = "otherMethod"]
+        safe static VAL: *mut ();
+    }
+    VAL
+}
+
+// CHECK: %struct._class_t = type { ptr, ptr, ptr, ptr, ptr }
+
+// CHECK: @"OBJC_CLASS_$_MyClass" = external global %struct._class_t
+// CHECK: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_MyClass", section "__DATA,__objc_classrefs,regular,no_dead_strip",
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+// CHECK-NOT: @"OBJC_CLASS_$_MyClass"
+// CHECK-NOT: @"OBJC_CLASSLIST_REFERENCES_$_
+
+// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [9 x i8] c"myMethod\00", section "__TEXT,__objc_methname,cstring_literals", align 1
+// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip",
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+// CHECK-NOT: @OBJC_METH_VAR_NAME_
+// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_
+
+// CHECK: @"OBJC_CLASS_$_OtherClass" = external global %struct._class_t
+// CHECK: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_OtherClass", section "__DATA,__objc_classrefs,regular,no_dead_strip",
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+
+// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [12 x i8] c"otherMethod\00", section "__TEXT,__objc_methname,cstring_literals", align 1
+// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip",
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+
+// CHECK-NOT: @OBJC_CLASS_NAME_
+// CHECK-NOT: @OBJC_MODULES
+
+// CHECK: load ptr, ptr @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}",
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}},
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+
+// CHECK: load ptr, ptr @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}",
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}},
+// x86_64_macos-SAME: align 8
+// aarch64_macos-SAME: align 8
+// i386_ios-SAME: align 4
+// x86_64_ios-SAME: align 8
+// armv7s_ios-SAME: align 4
+// aarch64_ios-SAME: align 8
+// aarch64_ios_sim-SAME: align 8
+
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 2}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
+
+// x86_64_macos-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// aarch64_macos-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// i386_ios: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// x86_64_ios: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// armv7s_ios-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// aarch64_ios-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// aarch64_ios_sim: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Class Properties", i32 64}
diff --git a/tests/codegen-llvm/darwin-objc-cross-crate.rs b/tests/codegen-llvm/darwin-objc-cross-crate.rs
new file mode 100644
index 00000000000..74ad9a27346
--- /dev/null
+++ b/tests/codegen-llvm/darwin-objc-cross-crate.rs
@@ -0,0 +1,58 @@
+// Test that Objective-C class and selector references inlined across crates
+// get defined in this CGU but non-inline references don't.
+
+// ignore-tidy-linelength
+//@ aux-build: darwin_objc_aux.rs
+//@ revisions: x86_64_macos aarch64_macos
+//@ [x86_64_macos] only-x86_64-apple-darwin
+//@ [aarch64_macos] only-aarch64-apple-darwin
+
+#![crate_type = "lib"]
+#![feature(darwin_objc)]
+
+use std::os::darwin::objc;
+
+extern crate darwin_objc_aux as aux;
+
+#[no_mangle]
+pub fn get_object_class() -> objc::Class {
+    aux::inline_get_object_class()
+}
+
+#[no_mangle]
+pub fn get_alloc_selector() -> objc::SEL {
+    aux::inline_get_alloc_selector()
+}
+
+#[no_mangle]
+pub fn get_string_class() -> objc::Class {
+    aux::never_inline_get_string_class()
+}
+
+#[no_mangle]
+pub fn get_init_selector() -> objc::SEL {
+    aux::never_inline_get_init_selector()
+}
+
+// CHECK: %struct._class_t = type { ptr, ptr, ptr, ptr, ptr }
+
+// CHECK: @"OBJC_CLASS_$_NSObject" = external global %struct._class_t
+// CHECK: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_NSObject", section "__DATA,__objc_classrefs,regular,no_dead_strip", align 8
+
+// CHECK: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [6 x i8] c"alloc\00", section "__TEXT,__objc_methname,cstring_literals", align 1
+// CHECK: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip", align 8
+
+// CHECK-NOT: @"OBJC_CLASS_$_NSString" = external global %struct._class_t
+// CHECK-NOT: @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}" = internal global ptr @"OBJC_CLASS_$_NSString"
+
+// CHECK-NOT: @OBJC_METH_VAR_NAME_.{{[0-9]+}} = private unnamed_addr constant [5 x i8] c"init\00"
+// CHECK-NOT: @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}} = internal externally_initialized global ptr @OBJC_METH_VAR_NAME_.{{[0-9]+}}
+
+// CHECK: load ptr, ptr @"OBJC_CLASSLIST_REFERENCES_$_.{{[0-9]+}}", align 8
+// CHECK: load ptr, ptr @OBJC_SELECTOR_REFERENCES_.{{[0-9]+}}, align 8
+
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Version", i32 2}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Version", i32 0}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
+// CHECK-NOT: !{{[0-9]+}} = !{i32 1, !"Objective-C Is Simulated", i32 32}
+// CHECK: !{{[0-9]+}} = !{i32 1, !"Objective-C Class Properties", i32 64}