1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -Wno-objc-root-class -emit-llvm -o - %s | FileCheck %s 2 3// -- classref for the message send in main() 4// 5// The class is declared with objc_class_stub, so LSB of the class pointer 6// must be set to 1. 7// 8// CHECK-LABEL: @"OBJC_CLASSLIST_REFERENCES_$_" = internal global ptr getelementptr (i8, ptr @"OBJC_CLASS_$_Base", i32 1), align 8 9 10// -- classref for the super message send in anotherClassMethod() 11// 12// Metaclasses do not use the "stub" mechanism and are referenced statically. 13// 14// CHECK-LABEL: @"OBJC_CLASSLIST_SUP_REFS_$_" = private global ptr @"OBJC_METACLASS_$_Derived", section "__DATA,__objc_superrefs,regular,no_dead_strip", align 8 15 16// -- classref for the super message send in anotherInstanceMethod() 17// 18// The class is declared with objc_class_stub, so LSB of the class pointer 19// must be set to 1. 20// 21// CHECK-LABEL: @"OBJC_CLASSLIST_SUP_REFS_$_.1" = private global ptr getelementptr (i8, ptr @"OBJC_CLASS_$_Derived", i32 1), section "__DATA,__objc_superrefs,regular,no_dead_strip", align 8 22 23// -- category list for class stubs goes in __objc_catlist2. 24// 25// CHECK-LABEL: @"OBJC_LABEL_STUB_CATEGORY_$" = private global [1 x ptr] [ptr @"_OBJC_$_CATEGORY_Derived_$_MyCategory"], section "__DATA,__objc_catlist2,regular,no_dead_strip", align 8 26 27__attribute__((objc_class_stub)) 28__attribute__((objc_subclassing_restricted)) 29@interface Base 30+ (void) classMethod; 31- (void) instanceMethod; 32@end 33 34__attribute__((objc_class_stub)) 35__attribute__((objc_subclassing_restricted)) 36@interface Derived : Base 37@end 38 39int main(void) { 40 [Base classMethod]; 41} 42// CHECK-LABEL: define{{.*}} i32 @main() 43// CHECK-NEXT: entry: 44// CHECK-NEXT: [[CLASS:%.*]] = call ptr @objc_loadClassref(ptr @"OBJC_CLASSLIST_REFERENCES_$_") 45// CHECK-NEXT: [[SELECTOR:%.*]] = load ptr, ptr @OBJC_SELECTOR_REFERENCES_ 46// CHECK-NEXT: call void @objc_msgSend(ptr noundef [[CLASS]], ptr noundef [[SELECTOR]]) 47// CHECK-NEXT: ret i32 0 48 49// CHECK-LABEL: declare extern_weak ptr @objc_loadClassref(ptr) 50// CHECK-SAME: [[ATTRLIST:#.*]] 51 52@implementation Derived (MyCategory) 53 54+ (void) anotherClassMethod { 55 [super classMethod]; 56} 57// CHECK-LABEL: define internal void @"\01+[Derived(MyCategory) anotherClassMethod]"(ptr noundef %self, ptr noundef %_cmd) #0 { 58// CHECK-NEXT: entry: 59// CHECK: [[SUPER:%.*]] = alloca %struct._objc_super, align 8 60// CHECK: [[METACLASS_REF:%.*]] = load ptr, ptr @"OBJC_CLASSLIST_SUP_REFS_$_", align 8 61// CHECK: [[DEST:%.*]] = getelementptr inbounds nuw %struct._objc_super, ptr [[SUPER]], i32 0, i32 1 62// CHECK: store ptr [[METACLASS_REF]], ptr [[DEST]], align 8 63// CHECK: call void @objc_msgSendSuper2(ptr noundef [[SUPER]], ptr noundef {{%.*}}) 64// CHECK: ret void 65 66- (void) anotherInstanceMethod { 67 [super instanceMethod]; 68} 69// CHECK-LABEL: define internal void @"\01-[Derived(MyCategory) anotherInstanceMethod]"(ptr noundef %self, ptr noundef %_cmd) #0 { 70// CHECK-NEXT: entry: 71// CHECK: [[SUPER:%.*]] = alloca %struct._objc_super, align 8 72// CHECK: [[CLASS_REF:%.*]] = call ptr @objc_loadClassref(ptr @"OBJC_CLASSLIST_SUP_REFS_$_.1") 73// CHECK: [[DEST:%.*]] = getelementptr inbounds nuw %struct._objc_super, ptr [[SUPER]], i32 0, i32 1 74// CHECK: store ptr [[CLASS_REF]], ptr [[DEST]], align 8 75// CHECK: call void @objc_msgSendSuper2(ptr noundef [[SUPER]], ptr noundef {{%.*}}) 76// CHECK: ret void 77 78@end 79 80// -- calls to objc_loadClassRef() are readnone 81// CHECK: attributes [[ATTRLIST]] = { nounwind nonlazybind memory(none) } 82