Home | History | Annotate | Download | only in CodeGenObjCXX
      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 
      6 id getObject();
      7 void callee();
      8 
      9 // Lifetime extension for binding a reference to an rvalue
     10 // CHECK-LABEL: define void @_Z5test0v()
     11 void 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_
     29 void 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 
     37 typedef __strong id strong_id;
     38 
     39 //CHECK: define void @_Z5test3v
     40 void 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
     51 void 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 
     60 void sink(__strong A* &&);
     61 
     62 // CHECK-LABEL: define void @_Z5test5RU8__strongP11objc_object
     63 void 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
     81 const __strong id &global_ref = getObject();
     82 
     83 // Note: we intentionally don't release the object.
     84 
     85