Home | History | Annotate | Download | only in CodeGenObjCXX
      1 // RUN: %clang_cc1 -std=c++11 -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: [[REF:%.*]] = alloca i8**, align 8
     42   // CHECK: call i8* @objc_initWeak
     43   // CHECK-NEXT: store i8**
     44   const __weak id &ref = strong_id();
     45   // CHECK-NEXT: call void @_Z6calleev()
     46   callee();
     47   // CHECK-NEXT: [[PTR:%.*]] = bitcast i8*** [[REF]] to i8*
     48   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTR]])
     49   // CHECK-NEXT: call void @objc_destroyWeak
     50   // CHECK-NEXT: ret void
     51 }
     52 
     53 // CHECK-LABEL: define void @_Z5test4RU8__strongP11objc_object
     54 void test4(__strong id &x) {
     55   // CHECK: call i8* @objc_retain
     56   __strong A* const &ar = x;
     57   // CHECK: store i32 17, i32*
     58   int i = 17;
     59   // CHECK: call void @objc_release(
     60   // CHECK: ret void
     61 }
     62 
     63 void sink(__strong A* &&);
     64 
     65 // CHECK-LABEL: define void @_Z5test5RU8__strongP11objc_object
     66 void test5(__strong id &x) {
     67   // CHECK:      [[REFTMP:%.*]] = alloca {{%.*}}*, align 8
     68   // CHECK:      [[I:%.*]] = alloca i32, align 4
     69   // CHECK:      [[OBJ_ID:%.*]] = call i8* @objc_retain(
     70   // CHECK-NEXT: [[OBJ_A:%.*]] = bitcast i8* [[OBJ_ID]] to [[A:%[a-zA-Z0-9]+]]*
     71   // CHECK-NEXT: store [[A]]* [[OBJ_A]], [[A]]** [[REFTMP:%[a-zA-Z0-9]+]]
     72   // CHECK-NEXT: call void @_Z4sinkOU8__strongP1A
     73   sink(x);  
     74   // CHECK-NEXT: [[OBJ_A:%[a-zA-Z0-9]+]] = load [[A]]*, [[A]]** [[REFTMP]]
     75   // CHECK-NEXT: [[OBJ_ID:%[a-zA-Z0-9]+]] = bitcast [[A]]* [[OBJ_A]] to i8*
     76   // CHECK-NEXT: call void @objc_release
     77   // CHECK-NEXT: [[IPTR1:%.*]] = bitcast i32* [[I]] to i8*
     78   // CHECK-NEXT: call void @llvm.lifetime.start(i64 4, i8* [[IPTR1]])
     79   // CHECK-NEXT: store i32 17, i32
     80   int i = 17;
     81   // CHECK-NEXT: [[IPTR2:%.*]] = bitcast i32* [[I]] to i8*
     82   // CHECK-NEXT: call void @llvm.lifetime.end(i64 4, i8* [[IPTR2]])
     83   // CHECK-NEXT: ret void
     84 }
     85 
     86 // CHECK-LABEL: define internal void @__cxx_global_var_init(
     87 // CHECK: call i8* @_Z9getObjectv
     88 // CHECK-NEXT: call i8* @objc_retainAutoreleasedReturnValue
     89 const __strong id &global_ref = getObject();
     90 
     91 // Note: we intentionally don't release the object.
     92 
     93