150
|
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 i8* getelementptr (i8, i8* bitcast (%struct._class_t* @"OBJC_CLASS_$_Base" to i8*), 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_$_" = internal global %struct._class_t* @"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" = internal global i8* getelementptr (i8, i8* bitcast (%struct._class_t* @"OBJC_CLASS_$_Derived" to i8*), 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_$" = internal global [1 x i8*] [i8* bitcast (%struct._category_t* @"_OBJC_$_CATEGORY_Derived_$_MyCategory" to i8*)], 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
|
|
39 int main() {
|
|
40 [Base classMethod];
|
|
41 }
|
|
42 // CHECK-LABEL: define i32 @main()
|
|
43 // CHECK-NEXT: entry:
|
|
44 // CHECK-NEXT: [[CLASS:%.*]] = call %struct._class_t* @objc_loadClassref(i8** @"OBJC_CLASSLIST_REFERENCES_$_")
|
|
45 // CHECK-NEXT: [[SELECTOR:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
|
|
46 // CHECK-NEXT: [[RECEIVER:%.*]] = bitcast %struct._class_t* [[CLASS]] to i8*
|
|
47 // CHECK-NEXT: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* [[RECEIVER]], i8* [[SELECTOR]])
|
|
48 // CHECK-NEXT: ret i32 0
|
|
49
|
|
50 // CHECK-LABEL: declare extern_weak %struct._class_t* @objc_loadClassref(i8**)
|
|
51 // CHECK-SAME: [[ATTRLIST:#.*]]
|
|
52
|
|
53 @implementation Derived (MyCategory)
|
|
54
|
|
55 + (void) anotherClassMethod {
|
|
56 [super classMethod];
|
|
57 }
|
|
58 // CHECK-LABEL: define internal void @"\01+[Derived(MyCategory) anotherClassMethod]"(i8* %self, i8* %_cmd) #0 {
|
|
59 // CHECK-NEXT: entry:
|
|
60 // CHECK: [[SUPER:%.*]] = alloca %struct._objc_super, align 8
|
|
61 // CHECK: [[METACLASS_REF:%.*]] = load %struct._class_t*, %struct._class_t** @"OBJC_CLASSLIST_SUP_REFS_$_", align 8
|
|
62 // CHECK: [[CAST_METACLASS_REF:%.*]] = bitcast %struct._class_t* [[METACLASS_REF]] to i8*
|
|
63 // CHECK: [[DEST:%.*]] = getelementptr inbounds %struct._objc_super, %struct._objc_super* [[SUPER]], i32 0, i32 1
|
|
64 // CHECK: store i8* [[CAST_METACLASS_REF]], i8** [[DEST]], align 8
|
|
65 // CHECK: call void bitcast (i8* (%struct._objc_super*, i8*, ...)* @objc_msgSendSuper2 to void (%struct._objc_super*, i8*)*)(%struct._objc_super* [[SUPER]], i8* {{%.*}})
|
|
66 // CHECK: ret void
|
|
67
|
|
68 - (void) anotherInstanceMethod {
|
|
69 [super instanceMethod];
|
|
70 }
|
|
71 // CHECK-LABEL: define internal void @"\01-[Derived(MyCategory) anotherInstanceMethod]"(%0* %self, i8* %_cmd) #0 {
|
|
72 // CHECK-NEXT: entry:
|
|
73 // CHECK: [[SUPER:%.*]] = alloca %struct._objc_super, align 8
|
|
74 // CHECK: [[CLASS_REF:%.*]] = call %struct._class_t* @objc_loadClassref(i8** @"OBJC_CLASSLIST_SUP_REFS_$_.1")
|
|
75 // CHECK: [[CAST_CLASS_REF:%.*]] = bitcast %struct._class_t* [[CLASS_REF]] to i8*
|
|
76 // CHECK: [[DEST:%.*]] = getelementptr inbounds %struct._objc_super, %struct._objc_super* [[SUPER]], i32 0, i32 1
|
|
77 // CHECK: store i8* [[CAST_CLASS_REF]], i8** [[DEST]], align 8
|
|
78 // CHECK: call void bitcast (i8* (%struct._objc_super*, i8*, ...)* @objc_msgSendSuper2 to void (%struct._objc_super*, i8*)*)(%struct._objc_super* [[SUPER]], i8* {{%.*}})
|
|
79 // CHECK: ret void
|
|
80
|
|
81 @end
|
|
82
|
|
83 // -- calls to objc_loadClassRef() are readnone
|
|
84 // CHECK: attributes [[ATTRLIST]] = { nounwind nonlazybind readnone }
|