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