blob: 79d207375920ba43b4cc9d173b309a079eb9f56d [file] [log] [blame]
Sebastian Redl32cf1f22012-02-17 08:42:25 +00001// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s
2
3namespace std {
4 typedef decltype(sizeof(int)) size_t;
5
6 // libc++'s implementation
7 template <class _E>
8 class initializer_list
9 {
10 const _E* __begin_;
11 size_t __size_;
12
13 initializer_list(const _E* __b, size_t __s)
14 : __begin_(__b),
15 __size_(__s)
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), __size_(0) {}
28
29 size_t size() const {return __size_;}
30 const _E* begin() const {return __begin_;}
31 const _E* end() const {return __begin_ + __size_;}
32 };
33}
34
35void 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: store i{{32|64}} 3
52 std::initializer_list<int> intlist{1, 2, i};
53}
54
55struct destroyme1 {
56 ~destroyme1();
57};
58struct destroyme2 {
59 ~destroyme2();
60};
Sebastian Redl25e640a2012-02-19 12:27:51 +000061struct witharg1 {
62 witharg1(const destroyme1&);
63 ~witharg1();
64};
Sebastian Redlbac5cf42012-02-19 12:27:56 +000065struct wantslist1 {
66 wantslist1(std::initializer_list<destroyme1>);
67 ~wantslist1();
68};
Sebastian Redl32cf1f22012-02-17 08:42:25 +000069
70void fn2() {
71 // CHECK: define void @_Z3fn2v
72 void target(std::initializer_list<destroyme1>);
73 // objects should be destroyed before dm2, after call returns
Sebastian Redl25e640a2012-02-19 12:27:51 +000074 // CHECK: call void @_Z6targetSt16initializer_listI10destroyme1E
Sebastian Redl32cf1f22012-02-17 08:42:25 +000075 target({ destroyme1(), destroyme1() });
76 // CHECK: call void @_ZN10destroyme1D1Ev
77 destroyme2 dm2;
78 // CHECK: call void @_ZN10destroyme2D1Ev
79}
80
81void fn3() {
82 // CHECK: define void @_Z3fn3v
83 // objects should be destroyed after dm2
84 auto list = { destroyme1(), destroyme1() };
85 destroyme2 dm2;
86 // CHECK: call void @_ZN10destroyme2D1Ev
87 // CHECK: call void @_ZN10destroyme1D1Ev
88}
Sebastian Redl25e640a2012-02-19 12:27:51 +000089
90void fn4() {
91 // CHECK: define void @_Z3fn4v
92 void target(std::initializer_list<witharg1>);
93 // objects should be destroyed before dm2, after call returns
94 // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
95 // CHECK: call void @_Z6targetSt16initializer_listI8witharg1E
96 target({ witharg1(destroyme1()), witharg1(destroyme1()) });
97 // CHECK: call void @_ZN8witharg1D1Ev
98 // CHECK: call void @_ZN10destroyme1D1Ev
99 destroyme2 dm2;
100 // CHECK: call void @_ZN10destroyme2D1Ev
101}
102
103void fn5() {
104 // CHECK: define void @_Z3fn5v
105 // temps should be destroyed before dm2
106 // objects should be destroyed after dm2
107 // CHECK: call void @_ZN8witharg1C1ERK10destroyme1
108 auto list = { witharg1(destroyme1()), witharg1(destroyme1()) };
109 // CHECK: call void @_ZN10destroyme1D1Ev
110 destroyme2 dm2;
111 // CHECK: call void @_ZN10destroyme2D1Ev
112 // CHECK: call void @_ZN8witharg1D1Ev
113}
Sebastian Redlbac5cf42012-02-19 12:27:56 +0000114
115void fn6() {
116 // CHECK: define void @_Z3fn6v
117 void target(const wantslist1&);
118 // objects should be destroyed before dm2, after call returns
119 // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E
120 // CHECK: call void @_Z6targetRK10wantslist1
121 target({ destroyme1(), destroyme1() });
122 // CHECK: call void @_ZN10wantslist1D1Ev
123 // CHECK: call void @_ZN10destroyme1D1Ev
124 destroyme2 dm2;
125 // CHECK: call void @_ZN10destroyme2D1Ev
126}
127
128void fn7() {
129 // CHECK: define void @_Z3fn7v
130 // temps should be destroyed before dm2
131 // object should be destroyed after dm2
132 // CHECK: call void @_ZN10wantslist1C1ESt16initializer_listI10destroyme1E
133 wantslist1 wl = { destroyme1(), destroyme1() };
134 // CHECK: call void @_ZN10destroyme1D1Ev
135 destroyme2 dm2;
136 // CHECK: call void @_ZN10destroyme2D1Ev
137 // CHECK: call void @_ZN10wantslist1D1Ev
138}