1 // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-macosx10.13.0 -fobjc-arc -fblocks -Wno-objc-root-class -O0 %s -S -emit-llvm -o - | FileCheck %s
2 // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-apple-macosx10.13.0 -fobjc-arc -fblocks -Wno-objc-root-class -O0 -xobjective-c++ -std=c++11 %s -S -emit-llvm -o - | FileCheck %s --check-prefix CHECKXX
4 #define EXT_RET __attribute__((objc_externally_retained))
11 // Suppress name mangling in C++ mode for the sake of check lines.
12 extern "C" void param(ObjTy *p);
13 extern "C" void local();
14 extern "C" void in_init();
15 extern "C" void anchor();
16 extern "C" void block_capture(ObjTy *);
17 extern "C" void esc(void (^)());
18 extern "C" void escp(void (^)(ObjTy *));
19 extern "C" void block_param();
22 void param(ObjTy *p) EXT_RET {
23 // CHECK-LABEL: define{{.*}} void @param
24 // CHECK-NOT: llvm.objc.
29 EXT_RET ObjTy *local = global;
30 // CHECK-LABEL: define{{.*}} void @local
31 // CHECK-NOT: llvm.objc.
36 // Test that we do the right thing when a variable appears in it's own
37 // initializer. Here, we release the value stored in 'wat' after overwriting
38 // it, in case it was somehow set to point to a non-null object while it's
39 // initializer is being evaluated.
40 EXT_RET ObjTy *wat = 0 ? wat : global;
42 // CHECK-LABEL: define{{.*}} void @in_init
43 // CHECK: [[WAT:%.*]] = alloca
44 // CHECK-NEXT: store {{.*}} null, {{.*}} [[WAT]]
45 // CHECK-NEXT: [[GLOBAL:%.*]] = load {{.*}} @global
46 // CHECK-NEXT: [[WAT_LOAD:%.*]] = load {{.*}} [[WAT]]
47 // CHECK-NEXT: store {{.*}} [[GLOBAL]], {{.*}} [[WAT]]
48 // CHECK-NEXT: [[CASTED:%.*]] = bitcast {{.*}} [[WAT_LOAD]] to
49 // CHECK-NEXT: call void @llvm.objc.release(i8* [[CASTED]])
51 // CHECK-NOT: llvm.objc.
55 void esc(void (^)(void));
57 void block_capture(ObjTy *obj) EXT_RET {
60 // CHECK-LABEL: define{{.*}} void @block_capture
61 // CHECK-NOT: llvm.objc.
62 // CHECK: call i8* @llvm.objc.retain
63 // CHECK-NOT: llvm.objc.
64 // CHECK: call void @esc
65 // CHECK-NOT: llvm.objc.
66 // CHECK: call void @llvm.objc.storeStrong({{.*}} null)
67 // CHECK-NOT: llvm.objc.
70 // CHECK-LABEL: define {{.*}} void @__copy_helper_block_
71 // CHECK-NOT: llvm.objc.
72 // CHECK: llvm.objc.storeStrong
73 // CHECK-NOT: llvm.objc.
76 // CHECK-LABEL: define {{.*}} void @__destroy_helper_block_
77 // CHECK-NOT: llvm.objc.
78 // CHECK: llvm.objc.storeStrong({{.*}} null)
79 // CHECK-NOT: llvm.objc.
83 void escp(void (^)(ObjTy *));
85 void block_param(void) {
86 escp(^(ObjTy *p) EXT_RET {});
88 // CHECK-LABEL: define internal void @__block_param_block_invoke
89 // CHECK-NOT: llvm.objc.
94 -(void)m1: (ObjTy *)w;
98 -(void)m1: (ObjTy *) w EXT_RET {
99 // CHECK-LABEL: define internal void @"\01-[Inter m1:]"
100 // CHECK-NOT: llvm.objc.
103 -(void)m2: (ObjTy *) w EXT_RET {
104 // CHECK-LABEL: define internal void @"\01-[Inter m2:]"
105 // CHECK-NOT: llvm.objc.
111 // Verify that the decltype(p) is resolved before 'p' is made implicitly const.
112 __attribute__((objc_externally_retained))
113 void foo(ObjTy *p, decltype(p) *) {}
114 // CHECKXX: _Z3fooP5ObjTyPU8__strongS0_