Home | History | Annotate | Download | only in CodeGenObjCXX
      1 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -O2 -std=c++11 -disable-llvm-optzns -o - %s | FileCheck %s
      2 
      3 // define void @_Z11simple_moveRU8__strongP11objc_objectS2_
      4 void simple_move(__strong id &x, __strong id &y) {
      5   // CHECK: = load i8**
      6   // CHECK: store i8* null
      7   // CHECK: = load i8**
      8   // CHECK: store i8*
      9   // CHECK-NEXT: call void @objc_release
     10   x = static_cast<__strong id&&>(y);
     11   // CHECK-NEXT: ret void
     12 }
     13 
     14 template<typename T>
     15 struct remove_reference {
     16   typedef T type;
     17 };
     18 
     19 template<typename T>
     20 struct remove_reference<T&> {
     21   typedef T type;
     22 };
     23 
     24 template<typename T>
     25 struct remove_reference<T&&> {
     26   typedef T type;
     27 };
     28 
     29 template<typename T> 
     30 typename remove_reference<T>::type&& move(T &&x) { 
     31   return static_cast<typename remove_reference<T>::type&&>(x); 
     32 }
     33 
     34 // CHECK-LABEL: define void @_Z12library_moveRU8__strongP11objc_objectS2_
     35 void library_move(__strong id &x, __strong id &y) {
     36   // CHECK: call nonnull i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
     37   // CHECK: load i8**
     38   // CHECK: store i8* null, i8**
     39   // CHECK: load i8***
     40   // CHECK-NEXT: load i8**
     41   // CHECK-NEXT: store i8*
     42   // CHECK-NEXT: call void @objc_release
     43   // CHECK-NEXT: ret void
     44   x = move(y);
     45 }
     46 
     47 // CHECK-LABEL: define void @_Z12library_moveRU8__strongP11objc_object
     48 void library_move(__strong id &y) {
     49   // CHECK: [[Y:%[a-zA-Z0-9]+]] = call nonnull i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
     50   // Load the object
     51   // CHECK-NEXT: [[OBJ:%[a-zA-Z0-9]+]] = load i8** [[Y]]
     52   // Null out y
     53   // CHECK-NEXT: store i8* null, i8** [[Y]]
     54   // Initialize x with the object
     55   // CHECK-NEXT: store i8* [[OBJ]], i8** [[X:%[a-zA-Z0-9]+]]
     56   id x = move(y);
     57 
     58   // CHECK-NEXT: store i32 17
     59   int i = 17;
     60   // CHECK-NEXT: [[OBJ:%[a-zA-Z0-9]+]] = load i8** [[X]]
     61   // CHECK-NEXT: call void @objc_release(i8* [[OBJ]])
     62   // CHECK-NEXT: ret void
     63 }
     64 
     65 // CHECK-LABEL: define void @_Z10const_moveRKU8__strongP11objc_object(
     66 void const_move(const __strong id &x) {
     67   // CHECK:      [[Y:%.*]] = alloca i8*,
     68   // CHECK:      [[X:%.*]] = call nonnull i8** @_Z4moveIRKU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_(
     69   // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]]
     70   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
     71   // CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
     72   // CHECK-NEXT: [[T0:%.*]] = load i8** [[Y]]
     73   // CHECK-NEXT: call void @objc_release(i8* [[T0]])
     74   id y = move(x);
     75 }
     76