[RISCV][FMV] Support target_clones (#85786)
[llvm-project.git] / clang / test / CodeGenObjC / externally-retained.m
blobfedf858bae2720684eee5486bc0bbae4b5ab5df3
1 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fobjc-arc -fblocks -Wno-objc-root-class -O0 %s -emit-llvm -o - | FileCheck %s
2 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.13.0 -fobjc-arc -fblocks -Wno-objc-root-class -O0 -xobjective-c++ -std=c++11 %s -emit-llvm -o - | FileCheck %s --check-prefix CHECKXX
4 #define EXT_RET __attribute__((objc_externally_retained))
6 @interface ObjTy @end
8 ObjTy *global;
10 #if __cplusplus
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();
20 #endif
22 void param(ObjTy *p) EXT_RET {
23   // CHECK-LABEL: define{{.*}} void @param
24   // CHECK-NOT: llvm.objc.
25   // CHECK: ret
28 void local(void) {
29   EXT_RET ObjTy *local = global;
30   // CHECK-LABEL: define{{.*}} void @local
31   // CHECK-NOT: llvm.objc.
32   // CHECK: ret
35 void in_init(void) {
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: call void @llvm.objc.release(ptr [[WAT_LOAD]])
50   // CHECK-NOT: llvm.objc.
51   // CHECK: ret
54 void esc(void (^)(void));
56 void block_capture(ObjTy *obj) EXT_RET {
57   esc(^{ (void)obj; });
59   // CHECK-LABEL: define{{.*}} void @block_capture
60   // CHECK-NOT: llvm.objc.
61   // CHECK: call ptr @llvm.objc.retain
62   // CHECK-NOT: llvm.objc.
63   // CHECK: call void @esc
64   // CHECK-NOT: llvm.objc.
65   // CHECK: call void @llvm.objc.storeStrong({{.*}} null)
66   // CHECK-NOT: llvm.objc.
67   // CHECK: ret
69   // CHECK-LABEL: define {{.*}} void @__copy_helper_block_
70   // CHECK-NOT: llvm.objc.
71   // CHECK: llvm.objc.storeStrong
72   // CHECK-NOT: llvm.objc.
73   // CHECK: ret
75   // CHECK-LABEL: define {{.*}} void @__destroy_helper_block_
76   // CHECK-NOT: llvm.objc.
77   // CHECK: llvm.objc.storeStrong({{.*}} null)
78   // CHECK-NOT: llvm.objc.
79   // CHECK: ret
82 void escp(void (^)(ObjTy *));
84 void block_param(void) {
85   escp(^(ObjTy *p) EXT_RET {});
87   // CHECK-LABEL: define internal void @__block_param_block_invoke
88   // CHECK-NOT: llvm.objc.
89   // CHECK: ret
92 @interface Inter
93 -(void)m1: (ObjTy *)w;
94 @end
96 @implementation Inter
97 -(void)m1: (ObjTy *) w EXT_RET {
98   // CHECK-LABEL: define internal void @"\01-[Inter m1:]"
99   // CHECK-NOT: llvm.objc.
100   // CHECK: ret
102 -(void)m2: (ObjTy *) w EXT_RET {
103   // CHECK-LABEL: define internal void @"\01-[Inter m2:]"
104   // CHECK-NOT: llvm.objc.
105   // CHECK: ret
107 @end
109 #if __cplusplus
110 // Verify that the decltype(p) is resolved before 'p' is made implicitly const.
111 __attribute__((objc_externally_retained))
112 void foo(ObjTy *p, decltype(p) *) {}
113 // CHECKXX: _Z3fooP5ObjTyPU8__strongS0_
114 #endif