1// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -O2 -disable-llvm-optzns -o - %s | FileCheck %s 2 3@interface A 4@end 5 6id getObject(); 7void callee(); 8 9// Lifetime extension for binding a reference to an rvalue 10// CHECK-LABEL: define void @_Z5test0v() 11void test0() { 12 // CHECK: call i8* @_Z9getObjectv 13 // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue 14 const __strong id &ref1 = getObject(); 15 // CHECK: call void @_Z6calleev 16 callee(); 17 // CHECK: call i8* @_Z9getObjectv 18 // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue 19 // CHECK-NEXT: call i8* @objc_autorelease 20 const __autoreleasing id &ref2 = getObject(); 21 // CHECK: call void @_Z6calleev 22 callee(); 23 // CHECK: call void @objc_release 24 // CHECK-NEXT: ret 25} 26 27// No lifetime extension when we're binding a reference to an lvalue. 28// CHECK-LABEL: define void @_Z5test1RU8__strongP11objc_objectRU6__weakS0_ 29void test1(__strong id &x, __weak id &y) { 30 // CHECK-NOT: release 31 const __strong id &ref1 = x; 32 const __autoreleasing id &ref2 = x; 33 const __weak id &ref3 = y; 34 // CHECK: ret void 35} 36 37typedef __strong id strong_id; 38 39//CHECK: define void @_Z5test3v 40void test3() { 41 // CHECK: call i8* @objc_initWeak 42 // CHECK-NEXT: store i8** 43 const __weak id &ref = strong_id(); 44 // CHECK-NEXT: call void @_Z6calleev() 45 callee(); 46 // CHECK-NEXT: call void @objc_destroyWeak 47 // CHECK-NEXT: ret void 48} 49 50// CHECK-LABEL: define void @_Z5test4RU8__strongP11objc_object 51void test4(__strong id &x) { 52 // CHECK: call i8* @objc_retain 53 __strong A* const &ar = x; 54 // CHECK: store i32 17, i32* 55 int i = 17; 56 // CHECK: call void @objc_release( 57 // CHECK: ret void 58} 59 60void sink(__strong A* &&); 61 62// CHECK-LABEL: define void @_Z5test5RU8__strongP11objc_object 63void test5(__strong id &x) { 64 // CHECK: [[REFTMP:%.*]] = alloca {{%.*}}*, align 8 65 // CHECK: [[OBJ_ID:%.*]] = call i8* @objc_retain( 66 // CHECK-NEXT: [[OBJ_A:%.*]] = bitcast i8* [[OBJ_ID]] to [[A:%[a-zA-Z0-9]+]]* 67 // CHECK-NEXT: store [[A]]* [[OBJ_A]], [[A]]** [[REFTMP:%[a-zA-Z0-9]+]] 68 // CHECK-NEXT: call void @_Z4sinkOU8__strongP1A 69 sink(x); 70 // CHECK-NEXT: [[OBJ_A:%[a-zA-Z0-9]+]] = load [[A]]** [[REFTMP]] 71 // CHECK-NEXT: [[OBJ_ID:%[a-zA-Z0-9]+]] = bitcast [[A]]* [[OBJ_A]] to i8* 72 // CHECK-NEXT: call void @objc_release 73 // CHECK-NEXT: store i32 17, i32 74 int i = 17; 75 // CHECK-NEXT: ret void 76} 77 78// CHECK-LABEL: define internal void @__cxx_global_var_init( 79// CHECK: call i8* @_Z9getObjectv 80// CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue 81const __strong id &global_ref = getObject(); 82 83// Note: we intentionally don't release the object. 84 85