Home | History | Annotate | Download | only in CodeGenObjCXX
      1 // RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=UNOPT
      2 // RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -fblocks -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -O -disable-llvm-optzns | FileCheck %s -check-prefix=CHECK -check-prefix=OPT
      3 
      4 typedef __strong id strong_id;
      5 typedef __weak id weak_id;
      6 
      7 // CHECK-LABEL: define void @_Z8test_newP11objc_object
      8 void test_new(id invalue) {
      9   // CHECK: [[INVALUEADDR:%.*]] = alloca i8*
     10   // UNOPT-NEXT: store i8* null, i8** [[INVALUEADDR]]
     11   // UNOPT-NEXT: call void @objc_storeStrong(i8** [[INVALUEADDR]], i8* [[INVALUE:%.*]])
     12   // OPT-NEXT: [[T0:%.*]] = call i8* @objc_retain(i8* [[INVALUE:%.*]])
     13   // OPT-NEXT: store i8* [[T0]], i8** [[INVALUEADDR]]
     14 
     15   // CHECK: call i8* @_Znwm
     16   // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
     17   // CHECK-NEXT: store i8* null, i8**
     18   new strong_id;
     19   // CHECK: call i8* @_Znwm
     20   // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
     21   // UNOPT-NEXT: store i8* null, i8**
     22   // OPT-NEXT: call i8* @objc_initWeak(i8** {{.*}}, i8* null)
     23   new weak_id;
     24 
     25   // CHECK: call i8* @_Znwm
     26   // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
     27   // CHECK-NEXT: store i8* null, i8**
     28   new __strong id;
     29   // CHECK: call i8* @_Znwm
     30   // CHECK-NEXT: {{bitcast i8\*.*to i8\*\*}}
     31   // UNOPT-NEXT: store i8* null, i8**
     32   // OPT-NEXT: call i8* @objc_initWeak(i8** {{.*}}, i8* null)
     33   new __weak id;
     34 
     35   // CHECK: call i8* @_Znwm
     36   // CHECK: call i8* @objc_retain
     37   // CHECK: store i8*
     38   new __strong id(invalue);
     39 
     40   // CHECK: call i8* @_Znwm
     41   // CHECK: call i8* @objc_initWeak
     42   new __weak id(invalue);
     43 
     44   // UNOPT: call void @objc_storeStrong
     45   // OPT: call void @objc_release
     46   // CHECK: ret void
     47 }
     48 
     49 // CHECK-LABEL: define void @_Z14test_array_new
     50 void test_array_new() {
     51   // CHECK: call i8* @_Znam
     52   // CHECK: store i64 17, i64*
     53   // CHECK: call void @llvm.memset.p0i8.i64
     54   new strong_id[17];
     55 
     56   // CHECK: call i8* @_Znam
     57   // CHECK: store i64 17, i64*
     58   // CHECK: call void @llvm.memset.p0i8.i64
     59   new weak_id[17];
     60   // CHECK: ret void
     61 }
     62 
     63 // CHECK-LABEL: define void @_Z11test_deletePU8__strongP11objc_objectPU6__weakS0_
     64 void test_delete(__strong id *sptr, __weak id *wptr) {
     65   // CHECK: br i1
     66   // UNOPT: call void @objc_storeStrong(i8** {{.*}}, i8* null)
     67   // OPT: load i8*, i8**
     68   // OPT-NEXT: call void @objc_release
     69   // CHECK: call void @_ZdlPv
     70   delete sptr;
     71 
     72   // CHECK: call void @objc_destroyWeak
     73   // CHECK: call void @_ZdlPv
     74   delete wptr;
     75 
     76   // CHECK: ret void
     77 }
     78 
     79 // CHECK-LABEL: define void @_Z17test_array_deletePU8__strongP11objc_objectPU6__weakS0_
     80 void test_array_delete(__strong id *sptr, __weak id *wptr) {
     81   // CHECK: icmp eq i8** [[BEGIN:%.*]], null
     82   // CHECK: [[LEN:%.*]] = load i64, i64* {{%.*}}
     83   // CHECK: [[END:%.*]] = getelementptr inbounds i8*, i8** [[BEGIN]], i64 [[LEN]]
     84   // CHECK-NEXT: icmp eq i8** [[BEGIN]], [[END]]
     85   // CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]],
     86   // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1
     87   // UNOPT-NEXT: call void @objc_storeStrong(i8** [[CUR]], i8* null)
     88   // OPT-NEXT: [[T0:%.*]] = load i8*, i8** [[CUR]]
     89   // OPT-NEXT: objc_release(i8* [[T0]])
     90   // CHECK-NEXT: icmp eq i8** [[CUR]], [[BEGIN]]
     91   // CHECK: call void @_ZdaPv
     92   delete [] sptr;
     93 
     94   // CHECK: icmp eq i8** [[BEGIN:%.*]], null
     95   // CHECK: [[LEN:%.*]] = load i64, i64* {{%.*}}
     96   // CHECK: [[END:%.*]] = getelementptr inbounds i8*, i8** [[BEGIN]], i64 [[LEN]]
     97   // CHECK-NEXT: icmp eq i8** [[BEGIN]], [[END]]
     98   // CHECK: [[PAST:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]],
     99   // CHECK-NEXT: [[CUR]] = getelementptr inbounds i8*, i8** [[PAST]], i64 -1
    100   // CHECK-NEXT: call void @objc_destroyWeak(i8** [[CUR]])
    101   // CHECK-NEXT: icmp eq i8** [[CUR]], [[BEGIN]]
    102   // CHECK: call void @_ZdaPv
    103   delete [] wptr;
    104 }
    105