1 // RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s 2 3 namespace std { 4 typedef decltype(sizeof(int)) size_t; 5 6 // libc++'s implementation with __size_ replaced by __end_ 7 template <class _E> 8 class initializer_list 9 { 10 const _E* __begin_; 11 const _E* __end_; 12 13 initializer_list(const _E* __b, const _E* __e) 14 : __begin_(__b), 15 __end_(__e) 16 {} 17 18 public: 19 typedef _E value_type; 20 typedef const _E& reference; 21 typedef const _E& const_reference; 22 typedef size_t size_type; 23 24 typedef const _E* iterator; 25 typedef const _E* const_iterator; 26 27 initializer_list() : __begin_(nullptr), __end_(nullptr) {} 28 29 size_t size() const {return __end_ - __begin_;} 30 const _E* begin() const {return __begin_;} 31 const _E* end() const {return __end_;} 32 }; 33 } 34 35 void fn1(int i) { 36 // CHECK: define void @_Z3fn1i 37 // temporary array 38 // CHECK: [[array:%[^ ]+]] = alloca [3 x i32] 39 // CHECK: getelementptr inbounds [3 x i32]* [[array]], i{{32|64}} 0 40 // CHECK-NEXT: store i32 1, i32* 41 // CHECK-NEXT: getelementptr 42 // CHECK-NEXT: store 43 // CHECK-NEXT: getelementptr 44 // CHECK-NEXT: load 45 // CHECK-NEXT: store 46 // init the list 47 // CHECK-NEXT: getelementptr 48 // CHECK-NEXT: getelementptr inbounds [3 x i32]* 49 // CHECK-NEXT: store i32* 50 // CHECK-NEXT: getelementptr 51 // CHECK-NEXT: getelementptr inbounds [3 x i32]* [[array]], i{{32|64}} 0, i{{32|64}} 3 52 // CHECK-NEXT: store i32* 53 std::initializer_list<int> intlist{1, 2, i}; 54 } 55 56 struct destroyme1 { 57 ~destroyme1(); 58 }; 59 struct destroyme2 { 60 ~destroyme2(); 61 }; 62 63 64 void fn2() { 65 // CHECK: define void @_Z3fn2v 66 void target(std::initializer_list<destroyme1>); 67 // objects should be destroyed before dm2, after call returns 68 target({ destroyme1(), destroyme1() }); 69 // CHECK: call void @_ZN10destroyme1D1Ev 70 destroyme2 dm2; 71 // CHECK: call void @_ZN10destroyme2D1Ev 72 } 73 74 void fn3() { 75 // CHECK: define void @_Z3fn3v 76 // objects should be destroyed after dm2 77 auto list = { destroyme1(), destroyme1() }; 78 destroyme2 dm2; 79 // CHECK: call void @_ZN10destroyme2D1Ev 80 // CHECK: call void @_ZN10destroyme1D1Ev 81 } 82